Atlas.py 119 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479
  1. # -*- coding: utf-8 -*-
  2. """
  3. /***************************************************************************
  4. Atlas
  5. A QGIS plugin
  6. Atlas
  7. Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
  8. -------------------
  9. begin : 2019-02-15
  10. git sha : $Format:%H$
  11. copyright : (C) 2019 by jan vrobel
  12. email : vrobel.jan@seznam.cz
  13. ***************************************************************************/
  14. /***************************************************************************
  15. * *
  16. * This program is free software; you can redistribute it and/or modify *
  17. * it under the terms of the GNU General Public License as published by *
  18. * the Free Software Foundation; either version 2 of the License, or *
  19. * (at your option) any later version. *
  20. * *
  21. ***************************************************************************/
  22. """
  23. from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QFileSystemWatcher, QRegExp,QDir
  24. from PyQt5.QtGui import QIcon, QPixmap, QRegExpValidator, QDoubleValidator
  25. from PyQt5.QtWidgets import QAction, QTreeWidget, QTreeWidgetItem, QMessageBox, QLabel, QProgressDialog, QDialog, QProgressBar,QListWidgetItem
  26. # Initialize Qt resources from file resources.py
  27. from .resources import *
  28. import re
  29. #from .flaskServer import *
  30. from multiprocessing import Process
  31. from pathlib import Path
  32. # Import the code for the DockWidget
  33. from builtins import str
  34. from builtins import range
  35. from builtins import object
  36. import json
  37. import zipfile
  38. import tempfile
  39. import configparser
  40. import shutil
  41. import uuid
  42. import copy
  43. import webbrowser
  44. from .Atlas_dockwidget import AtlasDockWidget
  45. import os.path
  46. import tempfile
  47. import qgis.core
  48. from qgis.core import *
  49. import platform
  50. import os
  51. import qgis.utils
  52. import qgis.gui
  53. from qgis.gui import QgsMapCanvas
  54. from qgis.core import QgsApplication
  55. from qgis.utils import iface
  56. from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QWidget, QInputDialog, QLineEdit, QFileDialog
  57. import requests
  58. import tempfile
  59. import time
  60. from urllib.request import urlopen
  61. import subprocess
  62. import threading
  63. #from flask import Flask, request, jsonify
  64. import base64
  65. import hashlib
  66. import html
  67. import re
  68. import urllib.parse
  69. from .ogr2ogr import main
  70. ## forms
  71. from .dlg_GetLayers import GetLayersDialog
  72. from .dlg_importMap import ImportMapDialog
  73. from .dlg_deleteMap import DeleteMapDialog
  74. from .dlg_importLayer import ImportLayerDialog
  75. from .dlg_addLayer import AddLayerDialog
  76. from .dlg_addMap import AddMapDialog
  77. from .dlg_createComposite import CreateCompositeDialog
  78. from .dlg_deleteLayerFromMap import DeleteLayerFromMapDialog
  79. from .dlg_editMap import EditMapDialog
  80. from .dlg_ConnectionManager import ConnectionManagerDialog
  81. from .dlg_userInfo import UserInfoDialog
  82. class Atlas:
  83. """QGIS Plugin Implementation."""
  84. def __init__(self, iface):
  85. """Constructor.
  86. :param iface: An interface instance that will be passed to this class
  87. which provides the hook by which you can manipulate the QGIS
  88. application at run time.
  89. :type iface: QgsInterface
  90. """
  91. # Save reference to the QGIS interface
  92. self.iface = iface
  93. # initialize plugin directory
  94. self.plugin_dir = os.path.dirname(__file__)
  95. ## init global variables
  96. # global filename
  97. self.client_id = None
  98. self.filename = None
  99. self.layerName = None
  100. self.username = 'browser'
  101. self.EPSG = 'EPSG:3857'
  102. self.composite = None
  103. self.thread1 = None
  104. self.compositeList = []
  105. self.compositeListOld = []
  106. self.CHUNK_SIZE = 1048576 ## s touto hodnotou pracuje layman klient (cca 1MB soubor)
  107. self.URI = "http://layman.lesprojekt.cz"
  108. self.access_token = None
  109. self.expires_in = None
  110. self.refresh_token = None
  111. self.laymanUsername = ""
  112. self.authHeader = None
  113. self.code_verifier = None
  114. self.code_challenge = None
  115. self.Agrimail = None
  116. self.loadedInMemory = False
  117. self.liferayServer = None
  118. self.laymanServer = None
  119. self.uri = 'http://layman.lesprojekt.cz/rest/'
  120. self.iface.layerTreeView().currentLayerChanged.connect(lambda: self.layerChanged())
  121. # global dlgGetLayers
  122. self.dlgGetLayers= GetLayersDialog()
  123. # initialize locale
  124. locale = QSettings().value('locale/userLocale')[0:2]
  125. locale_path = os.path.join(
  126. self.plugin_dir,
  127. 'i18n',
  128. 'Atlas_{}.qm'.format(locale))
  129. if os.path.exists(locale_path):
  130. self.translator = QTranslator()
  131. self.translator.load(locale_path)
  132. if qVersion() > '4.3.3':
  133. QCoreApplication.installTranslator(self.translator)
  134. # Declare instance attributes
  135. self.actions = []
  136. self.menu = self.tr(u'&Layman')
  137. # TODO: We are going to let the user set this up in a future iteration
  138. self.toolbar = self.iface.addToolBar(u'Layman')
  139. self.toolbar.setObjectName(u'Layman')
  140. #print "** INITIALIZING Atlas"
  141. self.pluginIsActive = False
  142. self.dockwidget = None
  143. ## prepare temp dir
  144. tempDir = tempfile.gettempdir() + os.sep + "atlas"
  145. try:
  146. os.mkdir(tempDir)
  147. print("Directory " , tempDir , " Created ")
  148. except FileExistsError:
  149. print("Directory " , tempDir , " already exists")
  150. # noinspection PyMethodMayBeStatic
  151. def tr(self, message):
  152. """Get the translation for a string using Qt translation API.
  153. We implement this ourselves since we do not inherit QObject.
  154. :param message: String for translation.
  155. :type message: str, QString
  156. :returns: Translated version of message.
  157. :rtype: QString
  158. """
  159. # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
  160. return QCoreApplication.translate('Layman', message)
  161. def add_action(
  162. self,
  163. icon_path,
  164. text,
  165. callback,
  166. enabled_flag=True,
  167. add_to_menu=True,
  168. add_to_toolbar=True,
  169. status_tip=None,
  170. whats_this=None,
  171. parent=None):
  172. icon = QIcon(icon_path)
  173. action = QAction(icon, text, parent)
  174. action.triggered.connect(callback)
  175. action.setEnabled(enabled_flag)
  176. if status_tip is not None:
  177. action.setStatusTip(status_tip)
  178. if whats_this is not None:
  179. action.setWhatsThis(whats_this)
  180. if add_to_toolbar:
  181. self.toolbar.addAction(action)
  182. if add_to_menu:
  183. self.iface.addPluginToMenu(
  184. self.menu,
  185. action)
  186. self.actions.append(action)
  187. return action
  188. def initGui(self):
  189. """Create the menu entries and toolbar icons inside the QGIS GUI."""
  190. #icon_path = ':/plugins/Atlas/icon.png'
  191. #self.add_action(
  192. # icon_path,
  193. # text=self.tr(u''),
  194. # callback=self.run,
  195. # parent=self.iface.mainWindow())
  196. #self.first_start = True
  197. ################## user
  198. self.textbox = QLabel(self.iface.mainWindow())
  199. # Set width
  200. self.textbox.setFixedWidth(140)
  201. # Add textbox to toolbar
  202. self.txtAction = self.toolbar.addWidget(self.textbox)
  203. # Set tooltip
  204. self.txtAction.setToolTip(self.tr(u'Current Row Number'))
  205. # Set callback
  206. self.textbox.setText("Layman")
  207. ################ end usericon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'login.png'
  208. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'login.png'
  209. self.menu_Connection = self.add_action(
  210. icon_path,
  211. text=self.tr(u'Login'),
  212. callback=self.run_login,
  213. enabled_flag=True,
  214. parent=self.iface.mainWindow())
  215. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'save.png'
  216. self.menu_saveLocalFile = self.add_action(
  217. icon_path,
  218. text=self.tr(u'Save as to JSON and SLD'),
  219. callback=self.saveLocalFile,
  220. enabled_flag=False,
  221. parent=self.iface.mainWindow())
  222. self.first_start = True
  223. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'file.png'
  224. self.menu_loadJson = self.add_action(
  225. icon_path,
  226. text=self.tr(u'Load from JSON'),
  227. callback=self.loadLocalFile,
  228. enabled_flag=False,
  229. parent=self.iface.mainWindow())
  230. self.first_start = True
  231. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'layers-up.png'
  232. self.menu_ImportLayerDialog = self.add_action(
  233. icon_path,
  234. text=self.tr(u'Export layer to server'),
  235. callback=self.run_ImportLayerDialog,
  236. enabled_flag=False,
  237. parent=self.iface.mainWindow())
  238. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'layers-down.png'
  239. self.menu_AddLayerDialog = self.add_action(
  240. icon_path,
  241. text=self.tr(u'Load layer from server'),
  242. callback=self.run_AddLayerDialog,
  243. enabled_flag=False,
  244. parent=self.iface.mainWindow())
  245. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'upload-map.png'
  246. self.menu_ImportMapDialog = self.add_action(
  247. icon_path,
  248. text=self.tr(u'Manage maps'),
  249. callback=self.run_ImportMapDialog,
  250. enabled_flag=False,
  251. parent=self.iface.mainWindow())
  252. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'download_map.png'
  253. self.menu_AddMapDialog = self.add_action(
  254. icon_path,
  255. text=self.tr(u'Load map from server'),
  256. callback=self.run_AddMapDialog,
  257. enabled_flag=False,
  258. parent=self.iface.mainWindow())
  259. #icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'delete.png'
  260. #self.menu_DeleteMapDialog = self.add_action(
  261. # icon_path,
  262. # text=self.tr(u'Delete map'),
  263. # callback=self.run_DeleteMapDialog,
  264. # enabled_flag=False,
  265. # parent=self.iface.mainWindow())
  266. #icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'globus.png'
  267. #self.menu_CreateCompositeDialog = self.add_action(
  268. # icon_path,
  269. # text=self.tr(u'Create map'),
  270. # callback=self.run_CreateCompositeDialog,
  271. # enabled_flag=False,
  272. # parent=self.iface.mainWindow())
  273. icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'account.svg'
  274. self.menu_UserInfoDialog = self.add_action(
  275. icon_path,
  276. text=self.tr(u'User info'),
  277. callback=self.run_UserInfoDialog,
  278. enabled_flag=False,
  279. parent=self.iface.mainWindow())
  280. #--------------------------------------------------------------------------
  281. def run_UserInfoDialog(self):
  282. self.dlg = UserInfoDialog()
  283. self.dlg.show()
  284. self.dlg.pushButton_logout.setStyleSheet("#pushButton_logout {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_logout:hover{background: #66ab27 ;}")
  285. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  286. userEndpoint = "http://layman.lesprojekt.cz/rest/current-user"
  287. r = requests.get(url = userEndpoint, headers = self.authHeader)
  288. res = r.text
  289. res = self.fromByteToJson(r.content)
  290. self.dlg.pushButton_logout.clicked.connect(lambda: self.logout())
  291. print(res['claims'])
  292. self.dlg.label_layman.setText(res['claims']['preferred_username'])
  293. self.dlg.label_agrihub.setText(res['claims']['email'])
  294. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  295. def run_EditMap(self, x):
  296. self.dlg = EditMapDialog()
  297. 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 ;}")
  298. 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 ;}")
  299. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  300. self.dlg.lineEdit_name.hide()
  301. self.dlg.label_2.hide()
  302. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  303. self.dlg.lineEdit_name.setText(self.compositeList[x]['name'])
  304. self.dlg.lineEdit_abstract.setText(self.compositeList[x]['abstract'])
  305. self.dlg.lineEdit_title.setText(self.compositeList[x]['title'])
  306. self.dlg.lineEdit_units.setText(self.compositeList[x]['units'])
  307. self.dlg.lineEdit_scale.setText(str(self.compositeList[x]['scale']))
  308. self.dlg.lineEdit_user.setText(self.compositeList[x]['user']['name'])
  309. self.dlg.lineEdit_xmin.setText(self.compositeList[x]['extent'][0])
  310. self.dlg.lineEdit_xmax.setText(self.compositeList[x]['extent'][2])
  311. self.dlg.lineEdit_ymin.setText(self.compositeList[x]['extent'][1])
  312. self.dlg.lineEdit_ymax.setText(self.compositeList[x]['extent'][3])
  313. self.dlg.rejected.connect(lambda: self.afterCloseEditMapDialog())
  314. self.dlg.pushButton_save.clicked.connect(lambda: self.modifyMap(x))
  315. self.dlg.rejected.connect(lambda: self.afterCloseCompositeDialog())
  316. self.dlg.show()
  317. result = self.dlg.exec_()
  318. def run_DeleteLayerFromMap(self):
  319. self.dlg = DeleteLayerFromMapDialog()
  320. 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']))
  321. #self.dlg.pushButton.clicked.connect(lambda: print(self.dlg.listWidget_2.currentRow()))
  322. layers = QgsProject.instance().mapLayers().values()
  323. for i in range (0, len(self.compositeList)):
  324. self.dlg.listWidget.addItem(self.compositeList[i]['name'])
  325. # self.dlg.pushButton.setEnabled(False)
  326. self.dlg.listWidget.itemClicked.connect(self.listCompositeLayers)
  327. self.dlg.listWidget_listLayers2.itemClicked.connect(self.showThumbnail)
  328. # self.dlg.listWidget_listMaps.itemClicked.connect(self.enableButton)
  329. self.dlg.show()
  330. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  331. result = self.dlg.exec_()
  332. def run_CreateCompositeDialog(self, fromImport = False):
  333. self.dlg = CreateCompositeDialog()
  334. self.dlg.label_info.hide()
  335. self.dlg.label_2.hide()
  336. self.dlg.lineEdit.hide()
  337. self.dlg.pushButton_CreateComposition.clicked.connect(lambda: self.createComposite(self.dlg.lineEdit.text(),self.dlg.lineEdit_2.text()))
  338. layers = QgsProject.instance().mapLayers().values()
  339. self.dlg.treeWidget.itemClicked.connect(self.setExtent)
  340. for layer in layers:
  341. # self.dlg.listWidget_listLayers.addItem(layer.name())
  342. if (layer.type() == QgsMapLayer.VectorLayer):
  343. item = QTreeWidgetItem([layer.name()])
  344. self.dlg.treeWidget.addTopLevelItem(item)
  345. ext = iface.mapCanvas().extent()
  346. self.dlg.lineEdit.setValidator(QRegExpValidator(QRegExp("[a-z]{1}[a-z0-9]{1,30}")))
  347. self.dlg.lineEdit_2.editingFinished.connect(self.checkNameCreateMap)
  348. self.dlg.lineEdit_3.setText(str(ext.xMinimum()))
  349. self.dlg.lineEdit_4.setText(str(ext.xMaximum()))
  350. self.dlg.lineEdit_5.setText(str(ext.yMinimum()))
  351. self.dlg.lineEdit_6.setText(str(ext.yMaximum()))
  352. self.dlg.pushButton_defaultExtent.clicked.connect(lambda: self.setDefaultExtent(ext))
  353. 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 ;}")
  354. 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 ;}")
  355. 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 ;}")
  356. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  357. self.dlg.show()
  358. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  359. if (fromImport):
  360. self.dlg.rejected.connect(lambda: self.afterCloseCompositeDialog())
  361. result = self.dlg.exec_()
  362. def run_ImportMapDialog(self):
  363. self.dlg = ImportMapDialog()
  364. self.dlg.label_import.hide()
  365. #self.dlg.listWidget_listLayers2.hide()
  366. self.dlg.pushButton_deleteMap.setEnabled(False)
  367. self.dlg.pushButton_editMeta.setEnabled(False)
  368. self.dlg.pushButton_addRaster.setEnabled(False)
  369. self.dlg.mMapLayerComboBox.setFilters(QgsMapLayerProxyModel.VectorLayer)
  370. self.dlg.pushButton.clicked.connect(lambda: self.addLayerToComposite(self.dlg.listWidget.currentRow()))
  371. self.dlg.pushButton_deleteMap.clicked.connect(lambda: self.deleteMap(self.dlg.listWidget.currentItem().text(),self.dlg.listWidget.currentRow()))
  372. # self.dlg.pushButton_deleteMap.clicked.connect(lambda: self.deleteMapFromCanvas(self.dlg.listWidget.currentRow()))
  373. self.dlg.pushButton_up.clicked.connect(lambda: self.reorderLayers(self.dlg.listWidget_listLayers.currentRow(), 1, self.dlg.listWidget.currentRow()))
  374. self.dlg.pushButton_down.clicked.connect(lambda: self.reorderLayers(self.dlg.listWidget_listLayers.currentRow(), -1, self.dlg.listWidget.currentRow()))
  375. self.dlg.pushButton_saveOrder.clicked.connect(lambda: self.saveReorder(self.dlg.listWidget.currentRow()))
  376. if not self.loadedInMemory:
  377. self.loadAllComposites()
  378. self.dlg.pushButton_addMap.clicked.connect(lambda: self.showAddMapDialog())
  379. layers = QgsProject.instance().mapLayers().values()
  380. for i in range (0, len(self.compositeList)):
  381. print(self.compositeList[i])
  382. #self.dlg.listWidget.addItem(self.compositeList[i]['name'])
  383. self.dlg.listWidget.addItem(self.compositeList[i]['title'])
  384. self.dlg.progressBar.hide()
  385. self.dlg.pushButton.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
  386. self.dlg.pushButton_addMap.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
  387. self.dlg.pushButton_addRaster.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
  388. self.dlg.pushButton_deleteLayers.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'minus.png'))
  389. self.dlg.pushButton_deleteMap.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'minus.png'))
  390. self.dlg.pushButton_editMeta.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'edit.png'))
  391. self.dlg.listWidget.itemClicked.connect(self.refreshLayerList)
  392. self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_deleteMap.setEnabled(True))
  393. self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_editMeta.setEnabled(True))
  394. self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_addRaster.setEnabled(True))
  395. self.dlg.listWidget_listLayers.itemClicked.connect(lambda: self.dlg.pushButton_down.setEnabled(True))
  396. self.dlg.listWidget_listLayers.itemClicked.connect(lambda: self.dlg.pushButton_up.setEnabled(True))
  397. self.dlg.pushButton_editMeta.clicked.connect(lambda: self.showEditMapDialog(self.dlg.listWidget.currentRow()))
  398. ###########nacitam vrstvy z laymana do comboboxu
  399. url = self.URI+'/rest/'+self.laymanUsername+'/layers'
  400. r = requests.get(url = url)
  401. # print(r.content())
  402. data = r.json()
  403. for row in range(0, len(data)):
  404. self.dlg.comboBox_raster.addItem(data[row]['name'])
  405. self.dlg.pushButton_addRaster.clicked.connect(lambda: self.addExistingLayerToComposite(self.dlg.comboBox_raster.currentText()))
  406. #### nahrát mapy ze serveru do comboboxu
  407. url = self.URI+'/rest/'+self.laymanUsername+'/maps'
  408. r = requests.get(url = url)
  409. data = r.json()
  410. for row in range(0, len(data)):
  411. self.dlg.comboBox_loadMap.addItem(data[row]['name'])
  412. self.dlg.pushButton_loadMap.clicked.connect(lambda: self.readMapJson(self.dlg.comboBox_loadMap.currentText(), 'WMS'))
  413. self.dlg.pushButton_loadMapWFS.clicked.connect(lambda: self.readMapJson(self.dlg.comboBox_loadMap.currentText(), 'WFS'))
  414. self.dlg.pushButton_loadMapWFS.hide()
  415. self.dlg.pushButton_loadMap.hide()
  416. self.dlg.comboBox_loadMap.hide()
  417. #############
  418. self.dlg.pushButton.setEnabled(False)
  419. self.dlg.pushButton_deleteLayers.setEnabled(False)
  420. self.dlg.listWidget_listLayers.itemClicked.connect(self.showSmallThumbnail)
  421. # self.dlg.listWidget_listLayers.itemClicked.connect(self.showThumbnail)
  422. self.dlg.listWidget.itemClicked.connect(self.enableButton)
  423. self.dlg.pushButton_deleteLayers.clicked.connect(lambda: self.deteteLayerFromComposite(self.dlg.listWidget.currentRow(),self.dlg.listWidget_listLayers.currentRow(), self.dlg.listWidget_listLayers.currentItem().text()))
  424. self.dlg.show()
  425. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  426. self.dlg.pushButton_saveOrder.setEnabled(False)
  427. 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 ;}")
  428. 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 ;}")
  429. 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 ;}")
  430. 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 ;}")
  431. 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 ;}")
  432. 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 ;}")
  433. 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 ;}")
  434. 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 ;}")
  435. 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 ;}")
  436. 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 ;}")
  437. 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 ;}")
  438. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  439. self.dlg.pushButton_saveOrder.setStyleSheet("#pushButton_saveOrder {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_saveOrder:hover{background: #66ab27 ;}#pushButton_saveOrder:disabled{background: #64818b ;}")
  440. result = self.dlg.exec_()
  441. def run_DeleteMapDialog(self):
  442. self.dlg = DeleteMapDialog()
  443. self.refreshListWidgetMaps()
  444. self.dlg.pushButton.setEnabled(False)
  445. self.dlg.treeWidget.itemClicked.connect(self.enableButton)
  446. self.dlg.pushButton.clicked.connect(lambda: self.deleteMapFromServer(self.dlg.treeWidget.selectedItems()[0].text(0)))
  447. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  448. self.dlg.show()
  449. result = self.dlg.exec_()
  450. def run_ImportLayerDialog(self):
  451. self.dlg = ImportLayerDialog()
  452. # self.dlg.pushButton.clicked.connect(lambda: self.postRequest(self.dlg.treeWidget.currentItem().text(0)))
  453. self.dlg.pushButton.clicked.connect(lambda: self.callPostRequest(self.dlg.treeWidget.selectedItems()))
  454. self.dlg.pushButton.setEnabled(False)
  455. # self.dlg.treeWidget.itemClicked.connect(self.enableButton)
  456. self.dlg.treeWidget.itemPressed.connect(self.enableButtonImport)
  457. self.dlg.treeWidget.itemClicked.connect(self.onItemClicked)
  458. layers = QgsProject.instance().mapLayers().values()
  459. for layer in layers:
  460. if (layer.type() == QgsMapLayer.VectorLayer):
  461. layerType = 'vector layer'
  462. else:
  463. layerType = 'raster layer'
  464. item = QTreeWidgetItem([layer.name(), layerType])
  465. if (layerType == 'vector layer'):
  466. self.dlg.treeWidget.addTopLevelItem(item)
  467. self.dlg.setWindowModality(Qt.ApplicationModal)
  468. 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 ;}")
  469. 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 ;}")
  470. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  471. self.dlg.show()
  472. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  473. result = self.dlg.exec_()
  474. def run_login(self):
  475. self.dlg = ConnectionManagerDialog()
  476. self.dlg.show()
  477. self.dlg.pushButton_Connect.setEnabled(False)
  478. if (os.path.isfile(os.getenv("HOME") + os.sep + ".layman" + os.sep +'layman_user.INI')):
  479. config = self.loadIni()
  480. if len(config['DEFAULT']['login']) > 0:
  481. self.Agrimail = config['DEFAULT']['login']
  482. self.dlg.pushButton_Connect.setEnabled(True)
  483. self.dlg.lineEdit_userName.setText(config['DEFAULT']['login'] + "@lesprojekt.cz")
  484. try:
  485. self.dlg.lineEdit_AgriID.setText(config['DEFAULT']['id'])
  486. self.dlg.lineEdit_server.setText(config['DEFAULT']['server'])
  487. self.dlg.lineEdit_serverLayman.setText(config['DEFAULT']['layman'])
  488. except:
  489. print("udaj v ini nenalezen")
  490. else:
  491. try:
  492. os.makedirs(os.getenv("HOME") + os.sep + ".layman")
  493. except:
  494. print("layman directory already exists")
  495. self.dlg.lineEdit_userName.setText("@lesprojekt.cz")
  496. self.dlg.pushButton_Connect.setEnabled(True)
  497. self.dlg.pushButton_ttt.hide()
  498. self.dlg.lineEdit_userName.textChanged.connect(self.checkUsername)
  499. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  500. self.dlg.pushButton_Connect.clicked.connect(lambda: self.openAuthLiferayUrl())
  501. self.dlg.pushButton_Continue.clicked.connect(lambda: self.getToken())
  502. self.dlg.pushButton_Continue.setEnabled(False)
  503. self.dlg.pushButton_ttt.clicked.connect(lambda: self.printVariables())
  504. 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 ;}")
  505. 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 ;}")
  506. 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 ;}")
  507. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  508. result = self.dlg.exec_()
  509. def run_AddMapDialog(self):
  510. url = self.URI+'/rest/'+self.laymanUsername+'/maps'
  511. print(url)
  512. r = requests.get(url = url)
  513. print(r.content)
  514. data = r.json()
  515. self.dlg = AddMapDialog()
  516. for row in range(0, len(data)):
  517. url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+data[row]['name']+'/file'
  518. r = requests.get(url = url)
  519. # print(r.content)
  520. d = r.json()
  521. print(d['title'])
  522. # item = QTreeWidgetItem([data[row]['name'], data[row]['url'], data[row]['uuid']])
  523. item = QTreeWidgetItem([d['title']])
  524. self.dlg.treeWidget.addTopLevelItem(item)
  525. self.dlg.pushButton.setEnabled(False)
  526. self.dlg.pushButton_mapWFS.setEnabled(False)
  527. self.dlg.label_info.hide()
  528. self.dlg.treeWidget.itemClicked.connect(self.showThumbnailMap)
  529. self.dlg.treeWidget.itemClicked.connect(self.enableButton)
  530. self.dlg.treeWidget.itemClicked.connect(self.enableLoadMapButtons)
  531. self.dlg.pushButton.clicked.connect(lambda: self.readMapJson(self.dlg.treeWidget.selectedItems()[0].text(0), 'WMS'))
  532. self.dlg.pushButton_mapWFS.clicked.connect(lambda: self.readMapJson(self.dlg.treeWidget.selectedItems()[0].text(0), 'WFS'))
  533. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  534. 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 ;}")
  535. 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 ;}")
  536. 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 ;}")
  537. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  538. self.dlg.show()
  539. result = self.dlg.exec_()
  540. def run_AddLayerDialog(self):
  541. if not self.loadedInMemory:
  542. self.loadAllComposites()
  543. url = self.URI+'/rest/'+self.laymanUsername+'/layers'
  544. r = requests.get(url = url)
  545. data = r.json()
  546. self.dlg = AddLayerDialog()
  547. self.dlg.pushButton_layerRedirect.hide()
  548. self.dlg.pushButton_layerRedirect.setEnabled(False)
  549. self.dlg.pushButton.setEnabled(False)
  550. self.dlg.pushButton_wfs.setEnabled(False)
  551. self.dlg.pushButton_delete.setEnabled(False)
  552. for row in range(0, len(data)):
  553. item = QTreeWidgetItem([self.getLayerTitle(data[row]['name'])])
  554. self.dlg.treeWidget.addTopLevelItem(item)
  555. self.dlg.pushButton_delete.clicked.connect(lambda: self.layerDelete(self.dlg.treeWidget.selectedItems()[0].text(0)))
  556. self.dlg.pushButton_layerRedirect.clicked.connect(lambda: self.layerInfoRedirect(self.dlg.treeWidget.selectedItems()[0].text(0)))
  557. self.dlg.pushButton.clicked.connect(lambda: self.readLayerJson(self.dlg.treeWidget.selectedItems()[0].text(0), "WMS"))
  558. self.dlg.pushButton_wfs.clicked.connect(lambda: self.readLayerJson(self.dlg.treeWidget.selectedItems()[0].text(0), "WFS"))
  559. self.dlg.treeWidget.itemClicked.connect(self.showThumbnail)
  560. self.dlg.treeWidget.itemClicked.connect(self.enableDeleteButton)
  561. self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
  562. self.dlg.setWindowModality(Qt.ApplicationModal)
  563. 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 ;}")
  564. 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 ;}")
  565. 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 ;}")
  566. 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 ;}")
  567. 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 ;}")
  568. self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
  569. self.dlg.show()
  570. result = self.dlg.exec_()
  571. def showExistingLayers(self,x):
  572. self.dlg.listWidget_listLayers.clear()
  573. for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):
  574. self.dlg.listWidget_listLayers.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
  575. #--------------------------- slots---------------------
  576. # @QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem, int)
  577. def onItemClicked(self, it, col):
  578. if (it.text(1) == 'raster layer'):
  579. self.dlg.pushButton.setEnabled(False)
  580. else:
  581. self.dlg.pushButton.setEnabled(True)
  582. def setExtent(self, it, col):
  583. layer = QgsProject.instance().mapLayersByName(it.text(0))
  584. ext = layer[0].extent()
  585. xmin = ext.xMinimum()
  586. xmax = ext.xMaximum()
  587. ymin = ext.yMinimum()
  588. ymax = ext.yMaximum()
  589. self.dlg.lineEdit_3.setText(str(xmin))
  590. self.dlg.lineEdit_4.setText(str(xmax))
  591. self.dlg.lineEdit_5.setText(str(ymin))
  592. self.dlg.lineEdit_6.setText(str(ymax))
  593. self.dlg.label_4.setText("Extent of canvas: " + it.text(0))
  594. def enableDeleteButton(self, item, col):
  595. self.dlg.pushButton.setEnabled(True)
  596. self.dlg.pushButton_wfs.setEnabled(True)
  597. self.dlg.pushButton_layerRedirect.setEnabled(True)
  598. self.dlg.pushButton_delete.setEnabled(True)
  599. def enableButton(self, item, col):
  600. self.dlg.pushButton.setEnabled(True)
  601. self.dlg.pushButton_mapWFS.setEnabled(True)
  602. self.dlg.pushButton_deleteLayers.setEnabled(True)
  603. self.dlg.pushButton_editMeta.setEnabled(True)
  604. self.dlg.pushButton_addRaster.setEnabled(True)
  605. def saveReorder(self, x):
  606. self.importMap(x, 'mod')
  607. self.dlg.pushButton_saveOrder.setEnabled(False)
  608. def checkUsername(self, name):
  609. n = name.split("@")
  610. if(len(n[0]) > 0):
  611. self.dlg.pushButton_Connect.setEnabled(True)
  612. self.Agrimail = n[0]
  613. else:
  614. self.dlg.pushButton_Connect.setEnabled(False)
  615. def checkLoadedMap(self, name):
  616. ## print(self.compositeList)
  617. loaded = False
  618. for i in range (0, len(self.compositeList)):
  619. if self.compositeList[i]['name'] == name:
  620. loaded = True
  621. return loaded
  622. def logout(self):
  623. self.menu_saveLocalFile.setEnabled(False)
  624. self.menu_loadJson.setEnabled(False)
  625. self.menu_ImportLayerDialog.setEnabled(False)
  626. self.menu_AddLayerDialog.setEnabled(False)
  627. self.menu_AddMapDialog.setEnabled(False)
  628. self.menu_ImportLayerDialog.setEnabled(False)
  629. self.menu_ImportMapDialog.setEnabled(False)
  630. self.menu_UserInfoDialog.setEnabled(False)
  631. self.textbox.setText("Layman")
  632. self.dlg.close()
  633. # self.flaskThread.join()
  634. # self.thread1.join() ## ukončujeme vlákno, které se stará o refresh tokenů OAUTH
  635. def enableLoadMapButtons(self, item):
  636. self.dlg.pushButton_mapWFS.setEnabled(True)
  637. def enableButtonImport(self, item, column):
  638. if (len(self.dlg.treeWidget.selectedItems()) > 0):
  639. self.dlg.pushButton.setEnabled(True)
  640. else:
  641. self.dlg.pushButton.setEnabled(False)
  642. def enableButton(self, item):
  643. try: ## addMap nemá combobox
  644. if (self.dlg.mMapLayerComboBox.count() > 0):
  645. self.dlg.pushButton.setEnabled(True)
  646. self.dlg.pushButton_mapWFS.setEnabled(True)
  647. else:
  648. self.dlg.pushButton.setEnabled(False)
  649. except:
  650. self.dlg.pushButton.setEnabled(True) ## addMap nemá combobox nastavujeme funkční tlačítko
  651. try:
  652. self.dlg.pushButton_deleteLayers.setEnabled(True) # pro formulář importMap
  653. except:
  654. pass
  655. def listCompositeLayers(self, it):
  656. self.dlg.listWidget_listLayers2.clear()
  657. for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):
  658. self.dlg.listWidget_listLayers2.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
  659. def deleteLayerThrowCompositions(self, name):
  660. for x in range (0,len(self.compositeList)):
  661. for i in range (0,len(self.compositeList[x]['layers'])):
  662. if (name == self.compositeList[x]['layers'][i]['params']['LAYERS']):
  663. inComposite = True
  664. print(self.compositeList[x]['layers'][i]['params']['LAYERS'])
  665. self.deteteLayerFromComposite(x, i, name)
  666. def checkLayersInComopsitions(self, name):
  667. inComposite = False
  668. for x in range (0,len(self.compositeList)):
  669. for i in range (0,len(self.compositeList[x]['layers'])):
  670. if (name == self.compositeList[x]['layers'][i]['params']['LAYERS']):
  671. inComposite = True
  672. print(self.compositeList[x]['layers'][i]['params']['LAYERS'])
  673. return inComposite
  674. def refreshCompositeList(self):
  675. self.dlg.listWidget.clear()
  676. print (len(self.compositeList))
  677. for i in range (0, len(self.compositeList)):
  678. # self.dlg.listWidget.addItem(self.compositeList[i]['name'])
  679. self.dlg.listWidget.addItem(self.compositeList[i]['title'])
  680. def refreshLayerList(self):
  681. self.dlg.listWidget_listLayers.clear()
  682. for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):
  683. self.dlg.listWidget_listLayers.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
  684. print(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
  685. def refreshListWidgetMaps(self):
  686. self.dlg.treeWidget.clear()
  687. url = self.URI+'/rest/'+self.laymanUsername+'/maps'
  688. print(url)
  689. r = requests.get(url = url)
  690. #print(r.content())
  691. data = r.json()
  692. for row in range(0, len(data)):
  693. item = QTreeWidgetItem([data[row]['name']])
  694. self.dlg.treeWidget.addTopLevelItem(item)
  695. def showAddMapDialog(self):
  696. self.old_dlg = self.dlg
  697. self.run_CreateCompositeDialog(True)
  698. ### connect
  699. def afterCloseCompositeDialog(self):
  700. self.dlg = self.old_dlg
  701. self.refreshCompositeList()
  702. def afterCloseEditMapDialog(self):
  703. self.dlg = self.old_dlg
  704. def showEditMapDialog(self, x):
  705. self.old_dlg = self.dlg
  706. self.run_EditMap(x)
  707. ############### pravdepodobne půjde smazat
  708. def refreshItems(self):
  709. self.dlg.listWidget_listLayers.clear()
  710. for i in range (0,len(self.compositeList)):
  711. # self.dlg.listWidget_listLayers.addItem(self.compositeList[i]['name'])
  712. self.dlg.listWidget_listLayers.addItem(self.compositeList[i]['title'])
  713. def saveEditedToComposite(self,x):
  714. self.compositeList[x]['abstract'] = self.dlg.lineEdit_abstract.text()
  715. self.compositeList[x]['title'] = self.dlg.lineEdit_title.text()
  716. def layerDelete(self, name):
  717. if (self.checkLayersInComopsitions(name) == True):
  718. msgbox = QMessageBox(QMessageBox.Question, "Delete layer", "This layers is included in other compositions. It will be delete from every composition.")
  719. msgbox.addButton(QMessageBox.Yes)
  720. msgbox.addButton(QMessageBox.No)
  721. msgbox.setDefaultButton(QMessageBox.No)
  722. reply = msgbox.exec()
  723. if (reply == QMessageBox.Yes):
  724. url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+name
  725. response = requests.delete(url, headers = self.authHeader)
  726. print(response.content)
  727. print(response)
  728. self.addLayerRefresh()
  729. try:
  730. self.deleteLayerThrowCompositions(name)
  731. except:
  732. pass
  733. else:
  734. url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+name
  735. response = requests.delete(url, headers = self.authHeader)
  736. print(response.content)
  737. print(response)
  738. self.addLayerRefresh()
  739. def addLayerRefresh(self):
  740. self.dlg.treeWidget.clear()
  741. url = self.URI+'/rest/'+self.laymanUsername+'/layers'
  742. r = requests.get(url = url)
  743. data = r.json()
  744. for row in range(0, len(data)):
  745. item = QTreeWidgetItem([data[row]['name']])
  746. self.dlg.treeWidget.addTopLevelItem(item)
  747. def checkIfMapExist(self, name):
  748. url = "http://layman.lesprojekt.cz/rest/"+self.laymanUsername+"/maps/"+str(name)+"/file"
  749. print(url)
  750. r = requests.get(url)
  751. print(r.content)
  752. if (r.status_code == 404):
  753. return False
  754. else:
  755. return True
  756. def reorderLayers(self, pos, order, x):
  757. self.dlg.pushButton_saveOrder.setEnabled(True)
  758. self.compositeList[x]['layers']
  759. i = 0
  760. compositeLength = len(self.compositeList[x]['layers'])
  761. if (pos + order < 0):
  762. QMessageBox.information(None, "Error", "Layer is already on the top level!")
  763. elif( pos + order == compositeLength):
  764. QMessageBox.information(None, "Error", "Layer is already on the bottom level!")
  765. else:
  766. for lay in self.compositeList[x]['layers']:
  767. #print (lay)
  768. if i == pos:
  769. pom = self.compositeList[x]['layers'][i]
  770. self.compositeList[x]['layers'][i] = self.compositeList[x]['layers'][i + order]
  771. self.compositeList[x]['layers'][i + order] = pom
  772. i = i + 1
  773. print(self.compositeList[x]['layers'])
  774. self.refreshLayerList()
  775. self.dlg.listWidget_listLayers.setCurrentRow(pos + order)
  776. def showThumbnail(self, it):
  777. try:
  778. layer = it.text(0) ##pro QTreeWidget
  779. except:
  780. layer = it.text()##pro listWidget
  781. try:
  782. url = self.URI+'/rest/' +self.laymanUsername+'/layers/'+str(layer).lower().replace(" ","_")+'/thumbnail'
  783. data = urlopen(url).read()
  784. pixmap = QPixmap(200, 200)
  785. pixmap.loadFromData(data)
  786. smaller_pixmap = pixmap.scaled(200, 200, Qt.KeepAspectRatio, Qt.FastTransformation)
  787. self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
  788. self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
  789. except:
  790. self.dlg.label_thumbnail.setText(' Unable to load thumbnail.')
  791. def showSmallThumbnail(self, it):
  792. try:
  793. layer = it.text(0) ##pro QTreeWidget
  794. except:
  795. layer = it.text()##pro listWidget
  796. try:
  797. url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layer).lower().replace(" ","_")+'/thumbnail'
  798. data = urlopen(url).read()
  799. pixmap = QPixmap(170, 170)
  800. pixmap.loadFromData(data)
  801. smaller_pixmap = pixmap.scaled(170, 170, Qt.KeepAspectRatio, Qt.FastTransformation)
  802. self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
  803. self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
  804. except:
  805. self.dlg.label_thumbnail.setText(' Unable to load thumbnail.')
  806. def showThumbnailMap(self, it):
  807. try:
  808. map = it.text(0) ##pro QTreeWidget
  809. except:
  810. map = it.text()##pro listWidget
  811. try:
  812. map = self.removeUnacceptableChars(str(map))
  813. url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+str(map).lower()+'/thumbnail'
  814. print(url)
  815. data = urlopen(url).read()
  816. pixmap = QPixmap(100, 100)
  817. pixmap.loadFromData(data)
  818. smaller_pixmap = pixmap.scaled(100, 100, Qt.KeepAspectRatio, Qt.FastTransformation)
  819. self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
  820. # self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
  821. except:
  822. self.dlg.label_thumbnail.setText(' Unable to load thumbnail.')
  823. def checkNameCreateMap(self):
  824. text = self.dlg.lineEdit_2.text()
  825. text = self.removeUnacceptableChars(text)
  826. print(text)
  827. if (self.checkIfMapExist(text)):
  828. self.dlg.pushButton_CreateComposition.setEnabled(False)
  829. self.dlg.label_info.show()
  830. else:
  831. self.dlg.pushButton_CreateComposition.setEnabled(True)
  832. self.dlg.label_info.hide()
  833. #----------------------------------------------------------
  834. def readLayerJson(self,layerName, service):
  835. if self.checkLayerOnLayman(layerName):
  836. layerNameTitle =layerName
  837. layerName = self.removeUnacceptableChars(layerName)
  838. url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layerName
  839. print (url)
  840. r = requests.get(url = url)
  841. data = r.json()
  842. if (service == "WMS"):
  843. print("loading WMS")
  844. print (data['wms']['url'])
  845. wmsUrl = data['wms']['url']
  846. format = 'png'
  847. epsg = 'EPSG:4326'
  848. self.loadWms(wmsUrl, layerName,layerNameTitle, format, epsg)
  849. if (service == "WFS"):
  850. wfsUrl = data['wfs']['url']
  851. print("loading WFS")
  852. self.loadWfs(wfsUrl, layerName, layerNameTitle)
  853. else:
  854. QMessageBox.information(None, "Layman", "Something went wrong with this layer: "+layerName)
  855. def loadAllComposites(self):
  856. url = self.URI+'/rest/' + self.laymanUsername + '/maps'
  857. try:
  858. r = requests.get(url = url)
  859. except:
  860. QMessageBox.information(None, "Error", "Connection with server failed!.")
  861. data = r.json()
  862. print(data)
  863. for i in data:
  864. print(i['name'])
  865. url = self.URI+'/rest/' + self.laymanUsername + '/maps/'+i['name']+'/file'
  866. r = requests.get(url = url)
  867. map = r.json()
  868. self.compositeList.append (map)
  869. self.loadedInMemory = True
  870. def readMapJson(self,name, service):
  871. nameWithDiacritics = name
  872. name = self.removeUnacceptableChars(name)
  873. print(name)
  874. print("readMapJson " + name)
  875. if not self.checkLoadedMap(name): ## je nactena mapa?
  876. # if True:
  877. print("debug in readMapJson - true")
  878. print(name)
  879. print(self.checkLoadedMap(name))
  880. url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name +'/file'
  881. r = requests.get(url = url)
  882. data = r.json()
  883. print(data)
  884. self.addComposite(data,service, name)
  885. try:
  886. self.refreshCompositeList() ## pouze pro import Form
  887. except:
  888. pass
  889. else:
  890. print("debug in readMapJson - false")
  891. url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name +'/file'
  892. r = requests.get(url = url)
  893. data = r.json()
  894. self.loadService(data,service, name)
  895. # QMessageBox.information(None, "Message", "This map is already loaded in memory. Loading only layers to canvas")
  896. def deleteMapFromServer(self,name):
  897. url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name
  898. response = requests.delete(url, headers = self.authHeader)
  899. print(response)
  900. QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
  901. # self.refreshMapList()
  902. self.refreshListWidgetMaps() ## pro treewidget
  903. def deleteMap(self,name, x):
  904. name = self.removeUnacceptableChars(name)
  905. url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name
  906. response = requests.delete(url, headers = self.authHeader)
  907. print(response)
  908. print(response.content)
  909. QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
  910. del (self.compositeList[x])
  911. self.refreshCompositeList()## pro import map form
  912. self.dlg.listWidget_listLayers.clear()
  913. def deleteMapandLayers(self,name, x):
  914. try:
  915. url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name
  916. response = requests.delete(url, headers = self.authHeader)
  917. QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
  918. except:
  919. QMessageBox.information(None, "Warning", "Deleting composition failed.")
  920. #self.refreshItems()
  921. self.deleteMapFromCanvas(x)
  922. self.dlg.listWidget_listLayers.clear()
  923. self.dlg.pushButton_deleteLayers.setEnabled(False)
  924. self.dlg.pushButton.setEnabled(False)
  925. self.dlg.pushButton_deleteMap.setEnabled(False)
  926. self.refreshCompositeList()
  927. def deleteMapFromCanvas(self, x):
  928. for i in range (0,len(self.compositeList[x]['layers'])): #[0]['params']['LAYERS']:
  929. name = self.compositeList[x]['layers'][i]['params']['LAYERS']
  930. lay = QgsProject.instance().mapLayersByName(name)[0]
  931. if (lay != None and lay.type() != QgsMapLayer.VectorLayer):
  932. QgsProject.instance().removeMapLayer(lay.id())
  933. del (self.compositeList[x])
  934. def deleteLayerFromCanvas(self, name):
  935. lay = QgsProject.instance().mapLayersByName(name)[0]
  936. if (lay != None and lay.type() != QgsMapLayer.VectorLayer):
  937. QgsProject.instance().removeMapLayer(lay.id())
  938. def getSelectedLayers(self):
  939. arr = self.dlg.listWidget_listLayers2.selectedItems()
  940. layers = []
  941. for a in arr:
  942. layer = QgsProject.instance().mapLayersByName(a.text())
  943. for lay in layer:
  944. if (lay.type() == QgsMapLayer.VectorLayer):
  945. layers.append(lay)
  946. return layers
  947. def run_getLayer(self):
  948. """Run method that performs all the real work"""
  949. # Create the dialog with elements (after translation) and keep reference
  950. # Only create GUI ONCE in callback, so that it will only load when the plugin is started
  951. if self.first_start == True:
  952. self.first_start = False
  953. self.dlgGetLayers.items.clear()
  954. # show the dialog
  955. self.dlgGetLayers.show()
  956. data= self.getExistingLayers()
  957. for x in range(len(data)):
  958. print(data[x]['name'])
  959. self.dlgGetLayers.items.addItem(data[x]['name'])
  960. # Run the dialog event loop
  961. print (self.dlgGetLayers)
  962. result = self.dlgGetLayers.exec_()
  963. # See if OK was pressed
  964. if result:
  965. # Do something useful here - delete the line containing pass and
  966. # substitute with your code.
  967. print ("test tlacitka")
  968. def onClosePlugin(self):
  969. """Cleanup necessary items here when plugin dockwidget is closed"""
  970. #print "** CLOSING Atlas"
  971. # disconnects
  972. self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
  973. self.flaskThread.terminate() ## killing daemons
  974. self.thread1.terminate()
  975. self.pluginIsActive = False
  976. def unload(self):
  977. """Removes the plugin menu item and icon from QGIS GUI."""
  978. #print "** UNLOAD Atlas"
  979. for action in self.actions:
  980. self.iface.removePluginMenu(
  981. self.tr(u'&Atlas'),
  982. action)
  983. self.iface.removeToolBarIcon(action)
  984. # remove the toolbar
  985. del self.toolbar
  986. #--------------------------------------------------------------------------
  987. def bounds(self, layers):
  988. extent = None
  989. for layer in layers:
  990. if layer.type() == 0:
  991. transform = QgsCoordinateTransform(layer.crs(), QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance()) # WGS 84 / UTM zone 33N
  992. try:
  993. layerExtent = transform.transform(layer.extent())
  994. except QgsCsException:
  995. print("exception in transform layer srs")
  996. layerExtent = QgsRectangle(-180, -90, 180, 90)
  997. if extent is None:
  998. extent = layerExtent
  999. else:
  1000. extent.combineExtentWith(layerExtent)
  1001. return (extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum())
  1002. def copySymbols(self,symbol, tempPath, fileNames):
  1003. for i in range(symbol.symbolLayerCount()):
  1004. sl = symbol.symbolLayer(i)
  1005. if isinstance(sl, QgsSvgMarkerSymbolLayer):
  1006. symbolPath = sl.path();
  1007. shutil.copy(symbolPath, tempPath)
  1008. print("Copying " + str(sl.path()))
  1009. fileNames.append(tempPath + os.sep + os.path.basename(symbolPath))
  1010. else:
  1011. print("Ignoring " + str(sl))
  1012. def setDefaultExtent (self, ext):
  1013. self.dlg.lineEdit_3.setText(str(ext.xMinimum()))
  1014. self.dlg.lineEdit_4.setText(str(ext.xMaximum()))
  1015. self.dlg.lineEdit_5.setText(str(ext.yMinimum()))
  1016. self.dlg.lineEdit_6.setText(str(ext.yMaximum()))
  1017. def loadJsonLayer(self, fileName):
  1018. name = (os.path.splitext(os.path.basename(fileName))[0])
  1019. vlayer = QgsVectorLayer(fileName, name,"ogr")
  1020. sldPath = os.path.splitext(fileName[:-4])[0] + ".sld"
  1021. qmlPath = os.path.splitext(fileName[:-4])[0] + ".qml"
  1022. print (sldPath)
  1023. sldExists = os.path.isfile(sldPath)
  1024. qmlExists = os.path.isfile(qmlPath)
  1025. if (qmlExists):
  1026. print("qml loaded")
  1027. vlayer.loadNamedStyle(qmlPath)
  1028. elif (sldExists):
  1029. vlayer.loadSldStyle(os.path.splitext(fileName)[0]+ ".sld")
  1030. print("sld loaded")
  1031. QgsProject.instance().addMapLayer(vlayer)
  1032. vlayer.triggerRepaint()
  1033. def checkLoadedLayer(self):
  1034. layers = iface.layerTreeView().selectedLayers()
  1035. if (len(layers) > 0):
  1036. self.json_export()
  1037. else:
  1038. QMessageBox.information(None, "Message", "You must load layer first!")
  1039. def getEmptyComposite(self, compositeName, compositeTitle):
  1040. compositeEPSG = "epsg:4326"
  1041. if (self.dlg.lineEdit_3.text() == "" or self.dlg.lineEdit_4.text() == "" or self.dlg.lineEdit_5.text() == "" or self.dlg.lineEdit_6.text() == ""):
  1042. ext = iface.mapCanvas().extent()
  1043. xmin = ext.xMinimum()
  1044. xmax = ext.xMaximum()
  1045. ymin = ext.yMinimum()
  1046. ymax = ext.yMaximum()
  1047. else:
  1048. xmin = self.dlg.lineEdit_3.text()
  1049. xmax = self.dlg.lineEdit_4.text()
  1050. ymin = self.dlg.lineEdit_5.text()
  1051. ymax = self.dlg.lineEdit_6.text()
  1052. abstract = self.dlg.lineEdit_7.text()
  1053. 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}}
  1054. self.dlg.close()
  1055. iface.messageBar().pushWidget(iface.messageBar().createMessage("Atlas:", " Kompozice " + compositeName + " byla úspešně vytvořena."), Qgis.Success, duration=3)
  1056. return comp
  1057. def loadLocalFile(self):
  1058. options = QFileDialog.Options()
  1059. dialog = QFileDialog()
  1060. 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 ;}");
  1061. fileName = dialog.getOpenFileName(None,"Load file", "","GeoJson Files (*.geojson);;Json Files (*.json)", options=options)
  1062. print ("načítám json ze souboru:" + fileName[0])
  1063. self.loadJsonLayer(fileName[0])
  1064. def modifyMap(self, x):
  1065. name = self.removeUnacceptableChars(self.dlg.lineEdit_title.text())
  1066. #self.compositeList[x]['name'] = self.dlg.lineEdit_name.text()
  1067. self.compositeList[x]['name'] = name
  1068. self.compositeList[x]['abstract'] = self.dlg.lineEdit_abstract.text()
  1069. self.compositeList[x]['title'] = self.dlg.lineEdit_title.text()
  1070. self.compositeList[x]['extent'][0] = self.dlg.lineEdit_xmin.text()
  1071. self.compositeList[x]['extent'][2] = self.dlg.lineEdit_xmax.text()
  1072. self.compositeList[x]['extent'][1] = self.dlg.lineEdit_ymin.text()
  1073. self.compositeList[x]['extent'][3] = self.dlg.lineEdit_ymax.text()
  1074. print(self.compositeList[x]['extent'])
  1075. print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
  1076. oldName = self.dlg.lineEdit_name.text()
  1077. response = requests.delete(self.URI+'/rest/'+self.laymanUsername+'/maps/'+oldName,headers = self.authHeader)
  1078. print(response.content)
  1079. self.dlg.close()
  1080. self.afterCloseEditMapDialog()
  1081. self.importMap(x, 'mod')
  1082. try:
  1083. self.refreshCompositeList()
  1084. iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Map metadata was saved successfully."), Qgis.Success, duration=3)
  1085. except:
  1086. pass
  1087. def saveLocalFile(self):
  1088. layer = self.iface.activeLayer()
  1089. print(layer.commitChanges()) ## změny uloženy
  1090. path = iface.activeLayer().dataProvider().dataSourceUri()
  1091. path = path.split("|")[0].replace("'","")
  1092. if (layer == None):
  1093. QMessageBox.information(None, "Message", "You must load layer first!")
  1094. else:
  1095. # defaultDir = QDir().home()
  1096. defaultDir = os.path.dirname(path)
  1097. print(defaultDir)
  1098. print(defaultDir +os.sep+ str(layer.name()) + ".geojson")
  1099. print(QDir().homePath() +os.sep+ str(layer.name()) + ".geojson")
  1100. dialog = QFileDialog()
  1101. dialog.setFileMode(1)
  1102. dialog.setDirectory(defaultDir)
  1103. print(dialog.directory().path())
  1104. # layer_name = dialog.getSaveFileName(None, "Save file", QDir().homePath() +os.sep+ str(layer.name()) + ".geojson", "*.geojson")
  1105. layer_name = dialog.getSaveFileName(None, "Save file", defaultDir +os.sep+ str(layer.name()) + ".geojson", "*.geojson")
  1106. self.json_export_local(layer_name[0], layer)
  1107. def json_export_local(self, layer_name, lay):
  1108. import shutil
  1109. filePath = self.getTempPath(layer_name)
  1110. ogr_driver_name = "GeoJSON"
  1111. project = QgsProject.instance()
  1112. fileNames = []
  1113. ## zde musí být zajištěna vektorová vrstva
  1114. layer = lay
  1115. layerType = layer.type()
  1116. if layerType == QgsMapLayer.VectorLayer:
  1117. renderer = layer.renderer()
  1118. hasIcon = False
  1119. if isinstance(renderer, QgsSingleSymbolRenderer):
  1120. self.copySymbols(renderer.symbol(), tempfile.gettempdir(), fileNames)
  1121. hasIcon = True
  1122. layerCrs = qgis.utils.iface.activeLayer().crs().authid()
  1123. crs = QgsCoordinateReferenceSystem(layerCrs)
  1124. result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, layer_name, "utf-8", crs, ogr_driver_name) # export jsonu do souboru
  1125. print(result2)
  1126. if(result2[0] == 2): ## testujeme zda není soubor otevřený v jiném procesu / návratový kod 2
  1127. tempFile = self.getTempPath(os.path.basename(layer_name.replace(".geojson", "") ))
  1128. print(tempFile)
  1129. #QMessageBox.information(None, "Layman", "It is not possible overwrite this file. File is already open in other process.")
  1130. sld_temp_filename = tempFile.replace("geojson", "sld")
  1131. qml_temp_filename = tempFile.replace("geojson", "qml")
  1132. layer.saveSldStyle(sld_temp_filename)
  1133. layer.saveNamedStyle(qml_temp_filename)
  1134. result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, tempFile, "utf-8", crs, ogr_driver_name)
  1135. print(result2)
  1136. if(result2[0] == 2):
  1137. QMessageBox.information(None, "Layman", "It is not possible overwrite this file. File is already open in other process.")
  1138. return
  1139. if os.path.basename(layer_name.replace(".geojson", "")) != '':
  1140. QgsProject.instance().removeMapLayer(layer.id())
  1141. print(tempFile, layer_name)
  1142. shutil.copy(tempFile, layer_name)
  1143. shutil.copy(sld_temp_filename, layer_name.replace(".geojson", ".sld"))
  1144. shutil.copy(qml_temp_filename, layer_name.replace(".geojson", ".qml"))
  1145. self.loadJsonLayer(layer_name)
  1146. else:
  1147. sld_filename = layer_name.replace("geojson", "sld")
  1148. qml_filename = layer_name.replace("geojson", "qml")
  1149. result3 = False
  1150. layer.saveSldStyle(sld_filename)
  1151. layer.saveNamedStyle(qml_filename)
  1152. def json_export(self, layer_name):
  1153. filePath = self.getTempPath(layer_name.lower())
  1154. ogr_driver_name = "GeoJSON"
  1155. project = QgsProject.instance()
  1156. fileNames = []
  1157. layer = QgsProject.instance().mapLayersByName(layer_name)[0]
  1158. layerType = layer.type()
  1159. if layerType == QgsMapLayer.VectorLayer:
  1160. renderer = layer.renderer()
  1161. hasIcon = False
  1162. if isinstance(renderer, QgsSingleSymbolRenderer):
  1163. self.copySymbols(renderer.symbol(), tempfile.gettempdir(), fileNames)
  1164. hasIcon = True
  1165. #layerCrs = qgis.utils.iface.activeLayer().crs().authid()
  1166. layerCrs = layer.crs().authid()
  1167. crs = QgsCoordinateReferenceSystem(layerCrs)# původně bylo
  1168. layer_filename = filePath
  1169. # crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
  1170. ##crs = layer.crs().authid()
  1171. # tempOut = layer_filename.replace(".geojson", "_2.geojson")
  1172. result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, layer_filename, "utf-8", crs, ogr_driver_name) # export jsonu do souboru
  1173. ##transformace
  1174. # input = tempOut
  1175. # out = layer_filename
  1176. # try:
  1177. # os.remove(layer_filename)
  1178. # except:
  1179. # pass
  1180. ## print("","-f", "Geojson", "-s_srs", layerCrs, "-t_srs", "epsg:4326", out, input)
  1181. # print("convert")
  1182. # print(main(["","-f", ogr_driver_name, "-s_srs", "EPSG:5514", "-t_srs", "EPSG:4326", out, input])) ## ogr2ogr
  1183. ##
  1184. sld_filename = filePath.replace("geojson", "sld").lower()
  1185. result3 = False
  1186. layer.saveSldStyle(sld_filename)
  1187. def checkValidAttributes(self, layer_name):
  1188. layers = QgsProject.instance().mapLayersByName(layer_name)
  1189. if len(layers) > 1:
  1190. for l in layers:
  1191. if (isinstance(l, QgsVectorLayer)):
  1192. print("xxx")
  1193. layers.clear()
  1194. layers.append(l)
  1195. break
  1196. isValid = True
  1197. pom =layers[0].getFeature(1)
  1198. for nam in pom.fields().names():
  1199. if (nam == ''):
  1200. isValid = False
  1201. return isValid
  1202. def checkWgsExtent(self, layer):
  1203. WgsXmax = 180
  1204. WgsXmin = -180
  1205. WgsYmax = 90
  1206. WgsYmin = -90
  1207. extent = layer.extent()
  1208. if (extent.xMaximum() > WgsXmax or extent.xMinimum() < WgsXmin or extent.yMaximum() > WgsYmax or extent.yMinimum() < WgsYmin ):
  1209. return False
  1210. else:
  1211. return True
  1212. def callPostRequest(self, layers):
  1213. for item in layers:
  1214. print (item.text(0))
  1215. self.postRequest(item.text(0))
  1216. #def transformLayer2(self, layer):
  1217. # pass
  1218. def setCurrentLayer(name):
  1219. layers = QgsProject.instance().mapLayersByName(name)
  1220. if(len(layers) >1):
  1221. layerss = QgsProject.instance().mapLayers().values()
  1222. i = 0
  1223. for layer in layerss:
  1224. if layers[0].name == layer.name():
  1225. if (i == item.currentIndex()):
  1226. i = i + 1
  1227. break
  1228. i = i + 1
  1229. return i
  1230. def transformLayer(self, layer):
  1231. layer = iface.activeLayer()
  1232. crsSrc = layer.crs()
  1233. print(crsSrc.authid())
  1234. crsDest = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
  1235. print(crsSrc, crsDest)
  1236. xform = QgsCoordinateTransform(crsSrc, crsDest, 5514, 4326)
  1237. feats=[]
  1238. if (layer.geometryType() == 0):
  1239. destLayer = QgsVectorLayer("Point?crs=EPSG:4326","lay","memory")
  1240. if (layer.geometryType() == 1):
  1241. destLayer = QgsVectorLayer("Linestring?crs=EPSG:4326","lay","memory")
  1242. if (layer.geometryType() == 2):
  1243. destLayer = QgsVectorLayer("Polygon?crs=EPSG:4326","lay","memory")
  1244. for f in layer.getFeatures():
  1245. g = f.geometry()
  1246. g.transform(xform)
  1247. print(g)
  1248. f.setGeometry(g)
  1249. feats.append(f)
  1250. destLayer.dataProvider().addFeatures(feats)
  1251. return destLayer
  1252. def postRequest(self, layer_name):
  1253. nameCheck = True
  1254. validExtent = True
  1255. layers = QgsProject.instance().mapLayersByName(layer_name)
  1256. # layer_name = self.removeUnacceptableChars(layer_name)
  1257. layers[0].setName(layer_name)
  1258. if len(layers) > 1:
  1259. for l in layers:
  1260. if (isinstance(l, QgsVectorLayer)):
  1261. layers.clear()
  1262. layers.append(l)
  1263. break
  1264. #if not (re.match('[a-zA-Z_]{1}', layer_name)): ## nesmí být nesmysl v názvu na prvním místě
  1265. # QMessageBox.information(None, "Layman", "Diacritics or number in first character is not allowed.")
  1266. # nameCheck = False
  1267. #if not (re.match('[a-zA-Z0-9]', layer_name)): ## není povolena diakritika
  1268. # QMessageBox.information(None, "Layman", "Diacritics is not allowed.")
  1269. # nameCheck = False
  1270. if (re.match('[0-9]{1}', layer_name)): ## nesmí být nesmysl v názvu na prvním místě
  1271. QMessageBox.information(None, "Layman", "Number in first character is not allowed.")
  1272. nameCheck = False
  1273. print(layer_name)
  1274. #if (layers[0].crs().authid() != 'EPSG:4323'):
  1275. # layers[0] = self.transformLayer(layers[0])
  1276. if not self.checkWgsExtent(layers[0]):
  1277. QMessageBox.information(None, "Layman", "Extent of layer is out of WGS 84 range. (EPSG: 4326)")
  1278. validExtent = False
  1279. if (nameCheck and validExtent):
  1280. crs = layers[0].crs().authid()
  1281. crs = "EPSG:4326"
  1282. data = { 'name' : str(layer_name).lower(), 'title' : str(layer_name), 'crs' : str(crs) }
  1283. if (self.checkValidAttributes(layer_name)):
  1284. if (self.checkExistingLayer(layer_name)):
  1285. print("vrstva již existuje")
  1286. msgbox = QMessageBox(QMessageBox.Question, "Layman", "Layer "+layer_name+" already exists in server. Do you want overwrite it´s geometry?")
  1287. msgbox.addButton(QMessageBox.Yes)
  1288. msgbox.addButton(QMessageBox.No)
  1289. msgbox.setDefaultButton(QMessageBox.No)
  1290. reply = msgbox.exec()
  1291. if (reply == QMessageBox.Yes):
  1292. print("vrstva již existuje")
  1293. self.json_export(layer_name)
  1294. geoPath = self.getTempPath(layer_name)
  1295. #try:
  1296. if (os.path.getsize(geoPath) > self.CHUNK_SIZE):
  1297. self.postInChunks(layer_name, "patch")
  1298. # iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
  1299. else:
  1300. self.patchLayer(layer_name, data)
  1301. iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
  1302. #except:
  1303. # iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was not imported successfully."), Qgis.Warning, duration=3)
  1304. else:
  1305. pass
  1306. else:
  1307. self.layerName = layer_name
  1308. # if (self.checkEpsg(layer_name)):
  1309. if(True): ##Pravděpodobně nebude třeba testovat EPSG, pokud se detekuje, je vrstva transformována.
  1310. # print (layer_name)
  1311. self.json_export(layer_name)
  1312. sldPath = self.getTempPath(self.layerName).replace("geojson", "sld")
  1313. geoPath = self.getTempPath(self.layerName)
  1314. if (os.path.getsize(geoPath) > self.CHUNK_SIZE):
  1315. self.postInChunks(layer_name, "post")
  1316. else:
  1317. if(os.path.isfile(sldPath)): ## existuje sld?
  1318. files = [('file', open(geoPath, 'rb')), ('sld', open(sldPath, 'rb'))]
  1319. else:
  1320. files = {'file': (geoPath, open(geoPath, 'rb')),}
  1321. print(files)
  1322. response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/layers', files=files, data = data, headers = self.authHeader)
  1323. print(response.content)
  1324. print(response.status_code)
  1325. if response.status_code == 200:
  1326. iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
  1327. else:
  1328. iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was not imported."), Qgis.Warning, duration=3)
  1329. else:
  1330. # QMessageBox.information(None, "Atlas", "Vrstva "+layer_name+" nelze nahrát. Použíjte EPSG:4326 nebo EPSG:3857")
  1331. QMessageBox.information(None, "Layman", "Use EPSG:4326")
  1332. else:
  1333. QMessageBox.information(None, "Layman", "Layer "+layer_name+" does not have attributes!")
  1334. def addExistingLayerToComposite(self, name):
  1335. x = self.dlg.listWidget.currentRow()
  1336. if self.checkLayerOnLayman(name):
  1337. inComposite = name in self.isRasterLayerInComposite(x, name)
  1338. if not(inComposite):
  1339. response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(name), verify=False)
  1340. res = self.fromByteToJson(response.content)
  1341. print(res)
  1342. wmsUrl = res['wms']['url']
  1343. 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":{}})
  1344. self.importMap(x, 'add', 1)
  1345. self.refreshLayerList()
  1346. else:
  1347. QMessageBox.information(None, "Message", "Composition already include layer "+name+"!")
  1348. else:
  1349. QMessageBox.information(None, "Layman", "Something went wrong with this layer: "+name)
  1350. def addExistingMapToMemory(self, name):
  1351. response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/maps/'+str(name), verify=False)
  1352. res = self.fromByteToJson(response.content)
  1353. print(res)
  1354. wmsUrl = res['wms']['url']
  1355. x = self.dlg.listWidget.currentRow()
  1356. 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":{}})
  1357. self.importMap(x, 'add', 1)
  1358. self.refreshLayerList()
  1359. def layerInfoRedirect(self, name):
  1360. url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + name
  1361. print(url)
  1362. response = requests.get(url)
  1363. r = self.fromByteToJson(response.content)
  1364. try:
  1365. url = r['metadata']['record_url']
  1366. webbrowser.open(url, new=2) ## redirect na micku pro více info
  1367. except:
  1368. QMessageBox.information(None, "Layman", "Link is unavailable.")
  1369. def checkLayerOnLayman(self, layer_name):
  1370. url = self.URI+'/rest/'+self.laymanUsername+"/layers/"+layer_name
  1371. r = requests.get(url = url, verify=False)
  1372. #print(r.content)
  1373. data = r.json()
  1374. try:
  1375. if data['wms']['status'] == 'NOT_AVAILABLE' or data['wms']['status'] == 'PENDING':
  1376. return False
  1377. else:
  1378. return True
  1379. except:
  1380. return True # validní vrstva nemá status
  1381. def addLayerToComposite(self,x):
  1382. self.compositeListOld = copy.deepcopy(self.compositeList) ## list pred upravou pro vraceni zmen
  1383. #layers = self.getSelectedLayers() #odkomentovat pro zapnuti nacitani vrstev z listwidgetu
  1384. layers = []
  1385. layers.append(self.dlg.mMapLayerComboBox.currentLayer())
  1386. successful = 0
  1387. print (len(layers))
  1388. try:
  1389. step = self.getProgressBarStep(len(layers))
  1390. except:
  1391. QMessageBox.information(None, "Layman", "No layer selected!")
  1392. for i in range (0, len(layers)):
  1393. print(type(layers[i]))
  1394. print (self.isLayerInComposite(x))
  1395. print (layers[i].name() in self.isLayerInComposite(x))
  1396. inComposite = layers[i].name() in self.isLayerInComposite(x)
  1397. layerName = self.removeUnacceptableChars(layers[i].name())
  1398. if (self.checkExistingLayer(layers[i].name()) and inComposite):
  1399. j = self.getLayerInCompositePosition(x)
  1400. print("j je: " + str(j))
  1401. # QMessageBox.information(None, "Message", "Composition already include layer "+layers[i].name()+"!")
  1402. # self.deteteLayerFromComposite(x, j, layers[i].name())
  1403. self.postRequest(layers[i].name())
  1404. layerName = self.removeUnacceptableChars(layers[i].name())
  1405. wmsStatus = 'PENDING'
  1406. j = 0
  1407. while ((wmsStatus == 'PENDING') and (j < 10)):
  1408. print (self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName))
  1409. response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName), verify=False)
  1410. res = self.fromByteToJson(response.content)
  1411. try:
  1412. wmsStatus = res['wms']['status']
  1413. except:
  1414. wmsStatus = "done"
  1415. time.sleep(1)
  1416. j = j + 1
  1417. #print(res)
  1418. #try:
  1419. # wmsUrl = res['wms']['url']
  1420. #except:
  1421. # wmsUrl = self.URI+'/geoserver/'+layers[i].name()+'/ows'
  1422. #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":{}})
  1423. #successful = successful + 1
  1424. #self.dlg.progressBar.setValue(self.dlg.progressBar.value()+step)
  1425. #self.importMap(x, "add", successful)
  1426. else:
  1427. self.postRequest(layers[i].name())
  1428. wmsStatus = 'PENDING'
  1429. j = 0
  1430. while ((wmsStatus == 'PENDING') and (j < 10)):
  1431. print (self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName))
  1432. response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layerName), verify=False)
  1433. res = self.fromByteToJson(response.content)
  1434. try:
  1435. wmsStatus = res['wms']['status']
  1436. except:
  1437. wmsStatus = "done"
  1438. time.sleep(1)
  1439. j = j + 1
  1440. print(res)
  1441. try:
  1442. wmsUrl = res['wms']['url']
  1443. except:
  1444. wmsUrl = self.URI+'/geoserver/'+layerName+'/ows'
  1445. self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(layerName),"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":{}})
  1446. successful = successful + 1
  1447. self.dlg.progressBar.setValue(self.dlg.progressBar.value()+step)
  1448. self.importMap(x, "add", successful)
  1449. def getProgressBarStep(self, count):
  1450. return (100/count)
  1451. def deteteLayerFromComposite(self, x, position, name): ## pro verzi s komboboxem
  1452. previousLayers = self.compositeList[x]['layers']
  1453. self.compositeList[x]['layers'] = []
  1454. for i in range (0,len(previousLayers)):
  1455. if (i != position):
  1456. self.compositeList[x]['layers'].append(previousLayers[i])
  1457. self.importMap(x, "del")
  1458. done = True
  1459. if (len(self.compositeList[x]['layers']) != 0 and len(self.compositeList[x]['layers']) != None):
  1460. for i in range (0, len(self.compositeList[x]['layers'])):
  1461. if (self.compositeList[x]['layers'][i]['params']['LAYERS'] == name):
  1462. done = False
  1463. if (done and QgsProject.instance().mapLayersByName(name)): ## kompozice může mít načtené vrstvy, které nejsou v canvasu
  1464. self.deleteLayerFromCanvas(name)
  1465. def importCleanComposite(self,x):
  1466. tempFile = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
  1467. with open(tempFile, 'w') as outfile:
  1468. json.dump(self.compositeList[x], outfile)
  1469. with open(tempFile, 'rb') as f:
  1470. d = json.load(f)
  1471. files = {'file': (tempFile, open(tempFile, 'rb')),}
  1472. data = { 'name' : self.compositeList[x]['name'], 'title' : self.compositeList[x]['title'], 'description' : self.compositeList[x]['abstract']}
  1473. print(self.URI+'/rest/'+self.laymanUsername+'/maps/')
  1474. #response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps/', data = data, files=files, headers = self.authHeader, verify=False)
  1475. print(self.authHeader)
  1476. response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader, verify=False)
  1477. print(response.content)
  1478. def showProgressBar(self, bar):
  1479. bar = QProgressBar()
  1480. bar.setRange(0,0) ## range 0,0 je nekonečný
  1481. self.showProgressBar(bar)
  1482. bar.show()
  1483. iface.mainWindow().statusBar().addWidget(bar)
  1484. def fromByteToJson(self, res):
  1485. pom = res
  1486. pom = pom.decode('utf_8')
  1487. pom = json.loads(pom)
  1488. return pom
  1489. def importMap(self, x, operation, s = 0): ##s je počet vrstev úspěšně nahraných na server
  1490. if (s != 0):
  1491. self.dlg.progressBar.show()
  1492. self.dlg.label_import.show()
  1493. tempFile = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
  1494. try:
  1495. existingLayers = self.isLayerInComposite(x)
  1496. except:
  1497. existingLayers = []
  1498. successful = s
  1499. with open(tempFile, 'w') as outfile:
  1500. json.dump(self.compositeList[x], outfile)
  1501. jsonPath = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
  1502. with open(jsonPath, 'rb') as f:
  1503. d = json.load(f)
  1504. files = {'file': (jsonPath, open(jsonPath, 'rb')),}
  1505. data = { 'name' : self.compositeList[x]['name'], 'title' : self.compositeList[x]['title'], 'description' : self.compositeList[x]['abstract']}
  1506. req = requests.get(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
  1507. mapCode = req.status_code ## test jestli vrstva na serveru existuje. Pokud ne = error 404
  1508. if (mapCode == 404):
  1509. if (operation == "add"):
  1510. msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete přidat do kompozice "+str(successful)+" vrstev?")
  1511. if (operation == "mod"):
  1512. #msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Do you want save changes?")
  1513. self.dlg.close()
  1514. self.afterCloseEditMapDialog()
  1515. print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
  1516. response = requests.delete(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'],headers = self.authHeader, verify=False)
  1517. print(response.content)
  1518. response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader)
  1519. self.dlg.show()
  1520. return
  1521. if (operation == "del"):
  1522. msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete smazat vybranou vrstvu?")
  1523. try: # jedná se o mod pokud je except
  1524. msgbox.addButton(QMessageBox.Yes)
  1525. msgbox.addButton(QMessageBox.No)
  1526. msgbox.setDefaultButton(QMessageBox.No)
  1527. reply = msgbox.exec()
  1528. except:
  1529. pass
  1530. if (reply == QMessageBox.Yes):
  1531. response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader)
  1532. print(response.content)
  1533. data = response.content
  1534. self.dlg.progressBar.hide()
  1535. # self.refreshItems()## refresh formuláře
  1536. if (operation != "mod"):
  1537. self.refreshLayerList()
  1538. else:
  1539. if (operation == "add"):
  1540. self.dlg.progressBar.setValue(0)
  1541. else:
  1542. print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
  1543. files = {'file': (jsonPath, open(jsonPath, 'rb')),}
  1544. response = requests.patch(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'], data = data, files=files, headers = self.authHeader, verify=False)
  1545. try:
  1546. self.refreshLayerList()
  1547. except:
  1548. ## nacházíme se v jiném formuláři, není co refreshovat
  1549. pass
  1550. #if (operation == "add"):
  1551. # print(len(existingLayers))
  1552. # msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
  1553. # #if(len(existingLayers) == 0):
  1554. # # #if (successful != 0):
  1555. # # msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
  1556. # #else:
  1557. # # # msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Kompozice již obsauje vrstvy: "+(', '.join(existingLayers))+". Chcete vybrané vrstvy opravdu znovu přidat?.")
  1558. # # msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
  1559. #if (operation == "del"):
  1560. # msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete smazat vybranou vrstvu?")
  1561. #if (operation == "mod"):
  1562. # msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete uložit upravenou mapu?")
  1563. #msgbox.addButton(QMessageBox.Yes)
  1564. #msgbox.addButton(QMessageBox.No)
  1565. #msgbox.setDefaultButton(QMessageBox.No)
  1566. #reply = msgbox.exec()
  1567. #if (reply == QMessageBox.Yes):
  1568. # print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
  1569. # files = {'file': (jsonPath, open(jsonPath, 'rb')),}
  1570. # response = requests.patch(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'], data = data, files=files, headers = self.authHeader, verify=False)
  1571. # try:
  1572. # self.refreshLayerList()
  1573. # except:
  1574. # ## nacházíme se v jiném formuláři, není co refreshovat
  1575. # pass
  1576. #if (reply == QMessageBox.No):
  1577. # self.compositeList = copy.deepcopy(self.compositeListOld)
  1578. # #self.refreshItems()##refresh formulare
  1579. # self.refreshLayerList()
  1580. try: ## některé formuláře nemají progress bar
  1581. self.dlg.progressBar.hide()
  1582. self.dlg.label_import.hide()
  1583. except:
  1584. pass
  1585. def deleteLayer(self, layerName):
  1586. url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + layerName
  1587. r = requests.delete(url)
  1588. print (r.content)
  1589. def getActiveLayer(self):
  1590. layer = self.iface.activeLayer()
  1591. return layer
  1592. def createComposite(self, name, title):
  1593. # if (name == "" or title == ""):
  1594. if (title == ""):
  1595. QMessageBox.information(None, "Message", "Není vyplněn titulek!")
  1596. else:
  1597. name = self.removeUnacceptableChars(title)
  1598. data = self.getEmptyComposite(name,title)
  1599. print (data)
  1600. self.compositeList.append(data)
  1601. x = len(self.compositeList) - 1
  1602. self.importCleanComposite(x)
  1603. try:
  1604. self.refreshCompositeList()
  1605. except:
  1606. pass
  1607. def patchLayer(self, layer_name, data):
  1608. print("patch layer")
  1609. self.json_export(layer_name)
  1610. self.layerName = layer_name.lower()
  1611. sldPath = self.getTempPath(self.layerName).replace("geojson", "sld")
  1612. geoPath = self.getTempPath(self.layerName)
  1613. ##self.layerName = self.layerName
  1614. print(sldPath)
  1615. if(os.path.isfile(sldPath)): ## existuje sld?
  1616. files = [('file', open(geoPath, 'rb')), ('sld', open(sldPath, 'rb'))]
  1617. print("sld")
  1618. else:
  1619. files = {'file': (geoPath, open(geoPath, 'rb')),}
  1620. print("ne sld")
  1621. layer_name = layer_name.lower()
  1622. layer_name = layer_name.replace(" ", "_")
  1623. url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + layer_name
  1624. print(url)
  1625. r = requests.patch(url, files=files, data = data, headers = self.authHeader, verify=False)
  1626. print(r.content)
  1627. def getTempPath(self, name):
  1628. print (name)
  1629. if type(name) is tuple:
  1630. return (name[0] + name[1])
  1631. else:
  1632. tempFile = tempfile.gettempdir() + os.sep + name +'.geojson'
  1633. return tempFile
  1634. def sendLayer(self):
  1635. layer = self.getActiveLayer()
  1636. if (layer == None):
  1637. QMessageBox.information(None, "Message", "Neexistuje žádná vrstva k uložení")
  1638. else:
  1639. self.json_export()
  1640. self.postRequest()
  1641. def getExistingLayers(self):
  1642. url = self.URI+'/rest/'+self.laymanUsername+"/layers"
  1643. r = requests.get(url = url)
  1644. data = r.json()
  1645. for x in range(len(data)):
  1646. print(data[x]['name'])
  1647. return data
  1648. def checkExistingLayer(self, layerName):
  1649. layerName = self.removeUnacceptableChars(layerName)
  1650. url = self.URI+'/rest/'+self.laymanUsername+"/layers"
  1651. r = requests.get(url = url)
  1652. data = r.json()
  1653. pom = set()
  1654. for x in range(len(data)):
  1655. pom.add((data[x]['name']))
  1656. layerName = layerName.replace(" ", "_").lower()
  1657. print(layerName)
  1658. print(pom)
  1659. if (layerName in pom):
  1660. return True
  1661. else:
  1662. return False
  1663. def removeUnacceptableChars(self, input):
  1664. input = input.lower()
  1665. input = input.replace("ř","r")
  1666. input = input.replace("š","s")
  1667. input = input.replace("ž","z")
  1668. input = input.replace("ů","u")
  1669. input = input.replace("ú","u")
  1670. input = input.replace(" ","_")
  1671. input = input.replace("é","e")
  1672. input = input.replace("í","i")
  1673. input = input.replace("ý","y")
  1674. input = input.replace("á","a")
  1675. input = input.replace("ó","o")
  1676. input = input.replace("č","c")
  1677. input = input.replace("ď","d")
  1678. input = input.replace("ě","e")
  1679. input = input.replace("ť","t")
  1680. input = re.sub(r'[?|$|.|!]',r'',input)
  1681. # iface.messageBar().pushWidget(iface.messageBar().createMessage("Layman:", "Diacritics in name of layer was replaced."), Qgis.Success, duration=3)
  1682. return input
  1683. def removeUnacceptableChars2(self, input):
  1684. input = input.encode('utf-8')
  1685. input = input.hex()
  1686. # iface.messageBar().pushWidget(iface.messageBar().createMessage("Layman:", "Diacritics in name of layer was replaced."), Qgis.Success, duration=3)
  1687. return input
  1688. def test (self):
  1689. item = self.dlgGetLayers.items.currentItem().text()
  1690. print( item)
  1691. def isLayerInComposite(self, x):
  1692. layers =[]
  1693. layers.append(self.dlg.mMapLayerComboBox.currentLayer())
  1694. print (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
  1695. req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
  1696. data = req.json()
  1697. print (data['abstract'])
  1698. print (len(self.compositeList[x]['layers']))
  1699. existingLayers = []
  1700. for i in range (0, len(data['layers'])):
  1701. for j in range (0, len(layers)):
  1702. if (data['layers'][i]['params']['LAYERS'] in layers[j].name() ):
  1703. existingLayers.append(data['layers'][i]['params']['LAYERS'])
  1704. return existingLayers
  1705. def getLayerInCompositePosition(self, x):
  1706. layers =[]
  1707. layers.append(self.dlg.mMapLayerComboBox.currentLayer())
  1708. print (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
  1709. req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
  1710. data = req.json()
  1711. print (data['abstract'])
  1712. print (len(self.compositeList[x]['layers']))
  1713. existingLayers = []
  1714. j = 0
  1715. for i in range (0, len(data['layers'])):
  1716. for j in range (0, len(layers)):
  1717. if (data['layers'][i]['params']['LAYERS'] in layers[j].name() ):
  1718. # existingLayers.append(data['layers'][i]['params']['LAYERS'])
  1719. j = i
  1720. print("founded")
  1721. return j
  1722. def isRasterLayerInComposite(self, x, name):
  1723. req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
  1724. data = req.json()
  1725. existingLayers = []
  1726. for i in range (0, len(data['layers'])):
  1727. if (data['layers'][i]['params']['LAYERS'] == name ):
  1728. existingLayers.append(data['layers'][i]['params']['LAYERS'])
  1729. return existingLayers
  1730. def addComposite(self, data, service, groupName = ''):
  1731. #self.compositeList.append (data)
  1732. print(len(data['layers']))
  1733. ##for x in range(0, len(data['layers'])):
  1734. for x in range(len(data['layers'])- 1, -1, -1):
  1735. # repairUrl = self.convertUrlFromHex(data['layers'][x]['url'])
  1736. repairUrl = self.URI+"/geoserver/"+self.laymanUsername+"/ows"
  1737. layerName = data['layers'][x]['params']['LAYERS']
  1738. format = data['layers'][x]['params']['FORMAT']
  1739. # epsg = str(data['groups']['projection']).upper()
  1740. epsg = 'EPSG:4326'
  1741. #abstract = data['data']['layers'][x]['params']['ABSTRACT']
  1742. wmsName = data['layers'][x]['params']['LAYERS']
  1743. print("groupName " +groupName)
  1744. print("groupName " +layerName)
  1745. print("groupName " +format)
  1746. print("groupName " +epsg)
  1747. layerNameTitle = self.getLayerTitle(layerName)
  1748. print("groupName " +layerNameTitle)
  1749. if service == 'WMS':
  1750. self.loadWms(repairUrl, layerName,layerNameTitle, format,epsg, groupName)
  1751. if service == 'WFS':
  1752. self.loadWfs(repairUrl, layerName,layerNameTitle, groupName)
  1753. def loadService(self, data, service, groupName = ''):
  1754. #print(len(data['layers']))
  1755. for x in range(len(data['layers'])- 1, -1, -1): ## descending order
  1756. #repairUrl = self.convertUrlFromHex(data['layers'][x]['url'])
  1757. repairUrl = self.URI+"/geoserver/"+self.laymanUsername+"/ows"
  1758. layerName = data['layers'][x]['params']['LAYERS']
  1759. format = data['layers'][x]['params']['FORMAT']
  1760. # epsg = str(data['groups']['projection']).upper()
  1761. epsg = 'EPSG:4326'
  1762. #abstract = data['data']['layers'][x]['params']['ABSTRACT']
  1763. wmsName = data['layers'][x]['params']['LAYERS']
  1764. layerNameTitle = data['layers'][x]['title']
  1765. if self.checkLayerOnLayman(layerName):
  1766. if service == 'WMS':
  1767. print("zzzzzzz" +layerName)
  1768. self.loadWms(repairUrl, layerName,layerNameTitle, format,epsg, groupName)
  1769. if service == 'WFS':
  1770. self.loadWfs(repairUrl, layerName,layerNameTitle, groupName)
  1771. else:
  1772. QMessageBox.information(None, "Layman", "Layer: "+layerName + " is corrupted and will not be loaded.")
  1773. def getLayerTitle(self, layerName):
  1774. layerName = self.removeUnacceptableChars(layerName)
  1775. url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layerName
  1776. r = requests.get(url = url)
  1777. data = r.json()
  1778. print(data)
  1779. title = data['title']
  1780. return title
  1781. def loadWms(self, url, layerName,layerNameTitle, format, epsg, groupName = ''):
  1782. print("debug")
  1783. print(groupName)
  1784. print(layerNameTitle)
  1785. print(layerName)
  1786. layerName = self.removeUnacceptableChars(layerName)
  1787. print(layerName)
  1788. epsg = "EPSG:4326"
  1789. urlWithParams = 'contextualWMSLegend=0&crs='+epsg+'&IgnoreReportedLayerExtents=1&dpiMode=7&featureCount=10&format=image/png&layers='+layerName+'&styles=&url=' + url
  1790. print(urlWithParams)
  1791. print("test")
  1792. print(layerNameTitle)
  1793. rlayer = QgsRasterLayer(urlWithParams, layerNameTitle, 'wms')
  1794. try:
  1795. print("extents")
  1796. print(rlayer.ignoreExtents())
  1797. except:
  1798. print("ignoreExtents works only with qgis 3.10 and higher")
  1799. pass # pro qgis 3.10 a vys
  1800. if (groupName != ''):
  1801. self.addWmsToGroup(groupName,rlayer)
  1802. else:
  1803. QgsProject.instance().addMapLayer(rlayer)
  1804. def loadWfs(self, url, layerName,layerNameTitle, groupName = ''):
  1805. layerName = self.removeUnacceptableChars(layerName)
  1806. epsg = 'EPSG:4326'
  1807. uri = self.URI+"/geoserver/"+self.laymanUsername+"/ows?srsname="+epsg+"&typename="+self.laymanUsername+":"+layerName+"&restrictToRequestBBOX=1&pagingEnabled=True&version=auto&request=GetFeature&service=WFS"
  1808. print(uri)
  1809. vlayer = QgsVectorLayer(uri, layerNameTitle, "WFS")
  1810. print(vlayer.isValid())
  1811. if (groupName != ''):
  1812. self.addWmsToGroup(groupName,vlayer)
  1813. else:
  1814. QgsProject.instance().addMapLayer(vlayer)
  1815. def addWmsToGroup(self, groupName, layer):
  1816. root = QgsProject.instance().layerTreeRoot()
  1817. group = root.findGroup(groupName)
  1818. if not(group):
  1819. group = root.addGroup(groupName)
  1820. group = self.reorderToTop(groupName)
  1821. QgsProject.instance().addMapLayer(layer,False)
  1822. group.insertChildNode(0,QgsLayerTreeLayer(layer))
  1823. def reorderToTop(self, name):
  1824. root = QgsProject.instance().layerTreeRoot()
  1825. for ch in root.children():
  1826. if ch.name() == name:
  1827. _ch = ch.clone()
  1828. root.insertChildNode(0, _ch)
  1829. root.removeChildNode(ch)
  1830. return _ch
  1831. def convertUrlFromHex(self, url):
  1832. url = url.replace('%3A',':')
  1833. url = url.replace('%2F','/')
  1834. url = url.replace('%3F','?')
  1835. url = url.replace('%3D','=')
  1836. url = url.replace('%26','&')
  1837. return url
  1838. def checkEpsg(self, name):
  1839. ret = False
  1840. layer = QgsProject.instance().mapLayersByName(name)
  1841. layerCRS = layer[0].crs().authid()
  1842. if ((layerCRS == 'EPSG:4326') or (layerCRS == 'EPSG:3857')):
  1843. ret = True
  1844. return ret
  1845. def registerLayer(self, name):
  1846. sldPath = self.getTempPath(name).replace("geojson", "sld").lower()
  1847. geoPath = self.getTempPath(name).lower()
  1848. url = "http://layman.lesprojekt.cz/rest/"+self.laymanUsername+"/layers"
  1849. files = {'sld': (sldPath, open(sldPath, 'rb')),} # nahrávám sld
  1850. payload = {
  1851. 'file': name.lower()+".geojson",
  1852. 'title': name
  1853. }
  1854. response = requests.request("POST", url, files = files, data=payload, headers = self.authHeader)
  1855. print(response.text)
  1856. def read_in_chunks(self, file_object): ## cca 1MB chunk převzato z laymana test klienta
  1857. chunk_size=self.CHUNK_SIZE
  1858. while True:
  1859. data = file_object.read(chunk_size)
  1860. if not data:
  1861. break
  1862. yield data
  1863. def postInChunks(self, layer_name, reqType):
  1864. print(reqType)
  1865. if (reqType == "patch"):
  1866. url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layer_name.lower().replace(" ", "_")
  1867. r = requests.delete(url,headers = self.authHeader)
  1868. # print(r.content)
  1869. self.registerLayer(layer_name)
  1870. layer_name = str(layer_name).lower()
  1871. filePath = os.path.join(tempfile.gettempdir(), "atlas_chunks" ) ## chunky se ukládají do adresáře v tempu
  1872. if not (os.path.exists(filePath)):
  1873. os.mkdir(filePath)
  1874. file = self.getTempPath(layer_name)
  1875. f = open(file, 'rb')
  1876. arr = []
  1877. for piece in self.read_in_chunks(f):
  1878. arr.append(piece)
  1879. ##layer_name = layer_name.lower()
  1880. url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layer_name.lower().replace(" ", "_")+'/chunk'
  1881. resumableFilename = layer_name+'.geojson'
  1882. layman_original_parameter = "file"
  1883. resumableTotalChunks = len(arr)
  1884. try:
  1885. for i in range (1, len(arr)+1): ##chunky jsou počítané od 1 proto +1
  1886. print("chunk" + str(i))
  1887. file = arr[i-1] # rozsekaná část souboru
  1888. resumableChunkNumber = i # cislo casti
  1889. payload = {
  1890. 'file' : "chunk"+str(i)+".geojson",
  1891. 'resumableFilename': resumableFilename,
  1892. 'layman_original_parameter': layman_original_parameter,
  1893. 'resumableChunkNumber': i,
  1894. 'resumableTotalChunks': resumableTotalChunks
  1895. }
  1896. f = open(filePath + os.sep+"chunk"+str(i)+".geojson", "wb")
  1897. f.write(bytearray(arr[i-1]))
  1898. f.close()
  1899. files = {'file': (layer_name.lower().replace(" ", "_")+".geojson", open(filePath +os.sep+ "chunk"+str(i)+".geojson", 'rb')),}
  1900. response = requests.post(url, files = files, data=payload, headers = self.authHeader)
  1901. print(response.content)
  1902. iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
  1903. except:
  1904. iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was not imported successfully!"), Qgis.Warning, duration=3)
  1905. ############################################# auth part############################
  1906. def startThread(self):
  1907. self.thread1 = threading.Thread(target=self.refreshToken)
  1908. self.thread1.start()
  1909. def refreshToken(self):
  1910. #self.expires_in = 60
  1911. path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "tsts.txt"
  1912. i = 0
  1913. tokenEndpoint = "https://www."+self.liferayServer+"/o/oauth2/token"
  1914. while (i < self.expires_in):
  1915. f = open(path, "a")
  1916. f.write(str(i))
  1917. f.close()
  1918. time.sleep(1)
  1919. if i == self.expires_in - 4:
  1920. data = {'grant_type':'refresh_token',
  1921. 'refresh_token': self.refresh_token,
  1922. 'client_id': self.client_id, ##'id-3462f94b-875c-9185-4ced-b69841f24b3',
  1923. 'redirect_uri':'http://localhost:3000/client/authn/oauth2-liferay/callback',
  1924. 'code_verifier':self.code_verifier ##'test'
  1925. }
  1926. r = requests.post(url = tokenEndpoint, data = data, headers = self.authHeader)
  1927. res = self.fromByteToJson(r.content)
  1928. self.access_token = res['access_token']
  1929. self.refresh_token = res['refresh_token']
  1930. self.expires_in = res['expires_in']
  1931. print(self.access_token)
  1932. self.setAuthHeader()
  1933. i = 0
  1934. else:
  1935. i += 1
  1936. def authOptained (self):
  1937. self.dlg.pushButton_Continue.setEnabled(True)
  1938. self.menu_Connection.setEnabled(True)
  1939. self.menu_saveLocalFile.setEnabled(False)
  1940. self.menu_loadJson.setEnabled(True)
  1941. self.menu_ImportLayerDialog.setEnabled(True)
  1942. self.menu_AddLayerDialog.setEnabled(True)
  1943. self.menu_AddMapDialog.setEnabled(True)
  1944. self.menu_ImportLayerDialog.setEnabled(True)
  1945. self.menu_ImportMapDialog.setEnabled(True)
  1946. # self.menu_DeleteMapDialog.setEnabled(True)
  1947. # self.menu_CreateCompositeDialog.setEnabled(True)
  1948. self.menu_UserInfoDialog.setEnabled(True)
  1949. self.textbox.setText("Layman: Logged user")
  1950. def getCodeVerifier(self):
  1951. code_verifier = base64.urlsafe_b64encode(os.urandom(40)).decode('utf-8')
  1952. code_verifier = re.sub('[^a-zA-Z0-9]+', '', code_verifier)
  1953. self.code_verifier = code_verifier
  1954. return (code_verifier)
  1955. def getCodeChallenge(self, code_verifier):
  1956. code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest()
  1957. code_challenge = base64.urlsafe_b64encode(code_challenge).decode('utf-8')
  1958. code_challenge = code_challenge.replace('=', '')
  1959. self.code_challenge = code_challenge
  1960. return (code_challenge)
  1961. def printVariables(self):
  1962. print (self.access_token)
  1963. print(self.refresh_token)
  1964. print(self.authHeader)
  1965. print(self.laymanUsername)
  1966. def getAuthCode(self):
  1967. path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "auth.txt"
  1968. f = open(path, "r")
  1969. ret = f.read()
  1970. f.close()
  1971. return ret
  1972. def getToken(self):
  1973. self.saveIni()
  1974. tokenEndpoint = "https://www."+self.liferayServer+"/o/oauth2/token"
  1975. # data to be sent to api
  1976. data = {'grant_type':'authorization_code',
  1977. 'client_id': self.client_id,
  1978. 'redirect_uri':'http://localhost:3000/client/authn/oauth2-liferay/callback',
  1979. 'code_verifier': self.code_verifier,
  1980. 'code': self.getAuthCode()}
  1981. # sending post request and saving response as response object
  1982. r = requests.post(url = tokenEndpoint, data = data, headers = self.authHeader)
  1983. res = self.fromByteToJson(r.content)
  1984. print (res)
  1985. try:
  1986. print(res['access_token'])
  1987. print(res['expires_in'])
  1988. print(res['refresh_token'])
  1989. except:
  1990. QMessageBox.information(None, "Message", "Autorization was not sucessfull! Please try it again.")
  1991. return
  1992. self.access_token = res['access_token']
  1993. self.refresh_token = res['refresh_token']
  1994. self.expires_in = res['expires_in']
  1995. self.setAuthHeader()
  1996. data ={
  1997. 'access_token': res['access_token'],
  1998. 'refresh_token': res['refresh_token'],
  1999. 'expires_in':res['expires_in']
  2000. }
  2001. path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "tokens.json"
  2002. with open(path, 'w') as outfile:
  2003. json.dump(data, outfile)
  2004. self.startThread()
  2005. self.registerUserIfNotExists()
  2006. self.dlg.close()
  2007. def setAuthHeader(self):
  2008. self.authHeader ={
  2009. "Authorization": "Bearer " + self.access_token,
  2010. "AuthorizationIssUrl" : 'https://www.'+self.liferayServer+'/o/oauth2/authorize'
  2011. }
  2012. def registerUserIfNotExists(self):
  2013. userEndpoint = "http://layman.lesprojekt.cz/rest/current-user"
  2014. #self.laymanUsername = self.dlg.lineEdit_userName.text()
  2015. id = self.client_id.replace('-', '')
  2016. user = {'username':self.Agrimail}
  2017. #user = self.Agrimail
  2018. print("authheader: "+ str(self.authHeader))
  2019. r = requests.patch(url = userEndpoint, data = user, headers = self.authHeader)
  2020. res = r.text
  2021. res = self.fromByteToJson(r.content)
  2022. print (res)
  2023. print(user)
  2024. print(res)
  2025. try:
  2026. # if res['message'] == 'User already reserved username.': # res['code'] == 34, code 35 je pokud již jiný uživatel má účet, který chceme registrovat
  2027. 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)
  2028. print("user exists")
  2029. self.laymanUsername = res['detail']['username']
  2030. #self.laymanUsername = res['username']
  2031. #else:
  2032. # self.laymanUsername = user['username']
  2033. except:
  2034. print("creating new user: " + res['username'])
  2035. self.laymanUsername = res['username']
  2036. #API_ENDPOINT = "http://layman.lesprojekt.cz/rest/current-user"
  2037. #headers ={
  2038. # "Authorization": "Bearer "+ self.access_token,
  2039. # "AuthorizationIssUrl" : 'https://www.'+self.liferayServer+'/o/oauth2/authorize'
  2040. #}
  2041. def openAuthLiferayUrl(self):
  2042. self.liferayServer = self.dlg.lineEdit_server.text()
  2043. self.URI = self.dlg.lineEdit_serverLayman.text()
  2044. self.getCodeChallenge(self.getCodeVerifier()) ##generování kódů
  2045. self.client_id = self.dlg.lineEdit_AgriID.text()
  2046. path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "auth.txt"
  2047. self.watcher = QFileSystemWatcher()
  2048. self.watcher.addPath(path)
  2049. self.watcher.fileChanged.connect(self.authOptained)
  2050. #################
  2051. print ("##### flask server is starting #####")
  2052. self.flaskThread = StartFlaskDaemon()
  2053. self.flaskThread.daemon = True
  2054. self.flaskThread.start()
  2055. url = 'https://www.'+self.liferayServer+'/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'
  2056. webbrowser.open(url, new=2)
  2057. def saveIni(self):
  2058. file = os.getenv("HOME") + os.sep + ".layman" + os.sep + 'layman_user.INI'
  2059. dir = os.getenv("HOME") + os.sep + ".layman"
  2060. if not (os.path.isdir(dir)):
  2061. try:
  2062. os.mkdir(dir)
  2063. except OSError:
  2064. print ("vytváření adresáře selhalo")
  2065. config = configparser.ConfigParser()
  2066. config['DEFAULT']['login'] = self.Agrimail
  2067. config['DEFAULT']['id'] = self.client_id
  2068. print("saveliferay" + self.liferayServer)
  2069. config['DEFAULT']['server'] = self.liferayServer
  2070. config['DEFAULT']['layman'] = self.URI
  2071. with open(file, 'w') as configfile:
  2072. config.write(configfile)
  2073. def loadIni(self):
  2074. file = os.getenv("HOME") + os.sep + ".layman" + os.sep +'layman_user.INI'
  2075. config = configparser.ConfigParser()
  2076. config.read(file)
  2077. return config
  2078. def layerChanged(self):
  2079. print(iface.activeLayer())
  2080. if (iface.activeLayer() != None):
  2081. self.menu_saveLocalFile.setEnabled(True)
  2082. else:
  2083. self.menu_saveLocalFile.setEnabled(False)
  2084. def run(self):
  2085. """Run method that loads and starts the plugin"""
  2086. if not self.pluginIsActive:
  2087. self.pluginIsActive = True
  2088. #print "** STARTING Atlas"
  2089. # dockwidget may not exist if:
  2090. # first run of plugin
  2091. # removed on close (see self.onClosePlugin method)
  2092. if self.dockwidget == None:
  2093. # Create the dockwidget (after translation) and keep reference
  2094. self.dockwidget = AtlasDockWidget()
  2095. # connect to provide cleanup on closing of dockwidget
  2096. self.dockwidget.closingPlugin.connect(self.onClosePlugin)
  2097. self.dockwidget.pushButton.clicked.connect(self.sendLayer)
  2098. self.dockwidget.pushButton_2.clicked.connect(self.loadLocalFile)
  2099. self.dockwidget.pushButton_3.clicked.connect(self.saveLocalFile)
  2100. self.dockwidget.pushButton_getLayers.clicked.connect(self.run_getLayer)
  2101. self.dlgGetLayers.pushButtonxx.clicked.connect(lambda: print(self.dlgGetLayers.items.currentItem().text()))
  2102. # show the dockwidget
  2103. # TODO: fix to allow choice of dock location
  2104. self.iface.addDockWidget(Qt.TopDockWidgetArea, self.dockwidget)
  2105. self.dockwidget.show()
  2106. class StartFlaskDaemon(threading.Thread):
  2107. def run(self):
  2108. from subprocess import Popen, PIPE
  2109. import platform
  2110. import sys
  2111. from pathlib import Path
  2112. d= os.path.dirname(Path(__file__).absolute()) + os.sep+"flask_listener" + os.sep + "flask_listener.py"
  2113. if platform.system() == 'Windows':
  2114. process = subprocess.Popen(["python", d],stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  2115. else:
  2116. process = subprocess.Popen(["python " + d],stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  2117. stdout, stderr = process.communicate()
  2118. print (stdout, stderr)
  2119. '''Start your thread here'''