Advertisement
Guest User

qgisplugin

a guest
Mar 14th, 2017
483
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 55.13 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. /***************************************************************************
  4. RimoPrinting
  5.                                 A QGIS plugin
  6. RimoPrinting
  7.                              -------------------
  8.        begin                : 2016-03-31
  9.        git sha              : $Format:%H$
  10.        copyright            : (C) 2016 by Bernd Loigge
  11.        email                : bernd.loigge@spl-tele.com
  12. ***************************************************************************/
  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 qgis.core import *
  24. from PyQt4.QtCore import Qt, QSettings, QTranslator, qVersion, QCoreApplication, QFileInfo, QVariant, QFile, QSizeF, QPyNullVariant, QUrl
  25. from PyQt4.QtGui import QAction, QIcon, QFileDialog, QPrinter, QPainter, QFont, QProgressBar
  26. from PyQt4.QtXml import QDomDocument
  27. from PyQt4.QtNetwork import QNetworkRequest
  28. from qgis.gui import QgsMessageBar, QgsMapCanvas, QgsLayerTreeMapCanvasBridge
  29. # Initialize Qt resources from file resources.py
  30. import resources
  31. import re
  32. # Import the code for the dialog
  33. from RimoPrinting_dialog import RimoPrintingDialog
  34. import os.path
  35. import sys
  36. sys.path.append('./requests')
  37. import requests
  38. import json
  39. import yaml
  40. import processing
  41. import time
  42. import inspect
  43. import csv
  44. import math
  45. import urllib
  46. import datetime
  47. import codecs
  48. #csv.register_dialect('RimoPrinting', delimiter=';')
  49. project = QgsProject.instance()
  50.  
  51. class RimoPrinting:
  52.     """QGIS Plugin Implementation."""
  53.  
  54.     def __init__(self, iface):
  55.         """Constructor.
  56.  
  57.        :param iface: An interface instance that will be passed to this class
  58.            which provides the hook by which you can manipulate the QGIS
  59.            application at run time.
  60.        :type iface: QgsInterface
  61.        """
  62.         # Save reference to the QGIS interface
  63.         self.iface = iface
  64.         # initialize plugin directory
  65.         self.plugin_dir = os.path.dirname(__file__).replace("\\", "/")
  66.         # initialize locale
  67.         locale = QSettings().value('locale/userLocale')[0:2]
  68.         locale_path = os.path.join(
  69.             self.plugin_dir,
  70.             'i18n',
  71.             'RimoPrinting_{}.qm'.format(locale))
  72.  
  73.         if os.path.exists(locale_path):
  74.             self.translator = QTranslator()
  75.             self.translator.load(locale_path)
  76.  
  77.             if qVersion() > '4.3.3':
  78.                 QCoreApplication.installTranslator(self.translator)
  79.  
  80.         # Create the dialog (after translation) and keep reference
  81.         self.dlg = RimoPrintingDialog()
  82.  
  83.         # Plugin Variables
  84.         self.loginStatus = False
  85.  
  86.         # Declare instance attributes
  87.         self.actions = []
  88.         self.menu = self.tr(u'&RimoPrinting')
  89.         # TODO: We are going to let the user set this up in a future iteration
  90.         self.toolbar = self.iface.addToolBar(u'RimoPrinting')
  91.         self.toolbar.setObjectName(u'RimoPrinting')
  92.  
  93.     # noinspection PyMethodMayBeStatic
  94.     def tr(self, message):
  95.         """Get the translation for a string using Qt translation API.
  96.  
  97.        We implement this ourselves since we do not inherit QObject.
  98.  
  99.        :param message: String for translation.
  100.        :type message: str, QString
  101.  
  102.        :returns: Translated version of message.
  103.        :rtype: QString
  104.        """
  105.         # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
  106.         return QCoreApplication.translate('RimoPrinting', message)
  107.  
  108.  
  109.     def add_action(
  110.         self,
  111.         icon_path,
  112.         text,
  113.         callback,
  114.         enabled_flag=True,
  115.         add_to_menu=True,
  116.         add_to_toolbar=True,
  117.         status_tip=None,
  118.         whats_this=None,
  119.         parent=None):
  120.         """Add a toolbar icon to the toolbar.
  121.  
  122.        :param icon_path: Path to the icon for this action. Can be a resource
  123.            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
  124.        :type icon_path: str
  125.  
  126.        :param text: Text that should be shown in menu items for this action.
  127.        :type text: str
  128.  
  129.        :param callback: Function to be called when the action is triggered.
  130.        :type callback: function
  131.  
  132.        :param enabled_flag: A flag indicating if the action should be enabled
  133.            by default. Defaults to True.
  134.        :type enabled_flag: bool
  135.  
  136.        :param add_to_menu: Flag indicating whether the action should also
  137.            be added to the menu. Defaults to True.
  138.        :type add_to_menu: bool
  139.  
  140.        :param add_to_toolbar: Flag indicating whether the action should also
  141.            be added to the toolbar. Defaults to True.
  142.        :type add_to_toolbar: bool
  143.  
  144.        :param status_tip: Optional text to show in a popup when mouse pointer
  145.            hovers over the action.
  146.        :type status_tip: str
  147.  
  148.        :param parent: Parent widget for the new action. Defaults None.
  149.        :type parent: QWidget
  150.  
  151.        :param whats_this: Optional text to show in the status bar when the
  152.            mouse pointer hovers over the action.
  153.  
  154.        :returns: The action that was created. Note that the action is also
  155.            added to self.actions list.
  156.        :rtype: QAction
  157.        """
  158.  
  159.         icon = QIcon(icon_path)
  160.         action = QAction(icon, text, parent)
  161.         action.triggered.connect(callback)
  162.         action.setEnabled(enabled_flag)
  163.  
  164.         if status_tip is not None:
  165.             action.setStatusTip(status_tip)
  166.  
  167.         if whats_this is not None:
  168.             action.setWhatsThis(whats_this)
  169.  
  170.         if add_to_toolbar:
  171.             self.toolbar.addAction(action)
  172.  
  173.         if add_to_menu:
  174.             self.iface.addPluginToVectorMenu(
  175.                 self.menu,
  176.                 action)
  177.  
  178.         self.actions.append(action)
  179.  
  180.         return action
  181.  
  182.     def initGui(self):
  183.         global project
  184.         """Create the menu entries and toolbar icons inside the QGIS GUI."""
  185.  
  186.         icon_path = self.plugin_dir + '/icon.png'
  187.         self.add_action(
  188.             icon_path,
  189.             text=self.tr(u'RimoPrinting'),
  190.             callback=self.run,
  191.             parent=self.iface.mainWindow())
  192.  
  193.  
  194.         #Disable Gui Elements for Login
  195.         if self.loginStatus == False:
  196.             self.disableLoginAndTenantGui(False)
  197.             self.dlg.pushButton_2.setEnabled(False)
  198.             self.dlg.pushButton_2.setEnabled(False)
  199.             self.dlg.comboBox_4.setEnabled(False)
  200.  
  201.         # Set Global Variables (For tasks without Login)
  202.         self.setGlobalVariables()
  203.  
  204.         # Set Plugin Variables
  205.         self.dlgIsActive = False
  206.         self.dataStore = {"regionData": None, "clusterData": None, "siteClusterData": None}
  207.         self.layerTree = QgsProject.instance().layerTreeRoot()
  208.  
  209.         # Populate Style List Changer
  210.         self.updateStyleListComboBox()
  211.  
  212.         # Login (Listener)
  213.         self.dlg.pushButton.clicked.connect(lambda: self.login(self.dlg.comboBox_8.currentText(), self.dlg.lineEdit.text(), self.dlg.lineEdit_2.text()))
  214.  
  215.         # Select a Tenant (Listener)
  216.         self.dlg.pushButton_2.clicked.connect(lambda: self.selectTenant(self.tenants[self.dlg.comboBox_4.currentIndex()]["tenant"]["asOop"], self.tenants[self.dlg.comboBox_4.currentIndex()]["tenant"]["id"]))
  217.  
  218.         # Create a Composer (Listener)
  219.         self.dlg.pushButton_3.clicked.connect(lambda: self.createPrintComposer())
  220.  
  221.         # Refresh All Data layerTree (Listener)
  222.         self.dlg.pushButton_4.clicked.connect(lambda: self.refreshAllRimoDataConnections())
  223.  
  224.         # Load Backbone Region Data
  225.         self.dlg.pushButton_5.clicked.connect(lambda: self.loadBackboneRegionData())
  226.  
  227.         # Change Layer Styles
  228.         self.dlg.pushButton_6.clicked.connect(lambda: self.changeLayerStyles())
  229.  
  230.         # Update Layer Style Folder
  231.         self.dlg.pushButton_7.clicked.connect(lambda: self.updateStyleListComboBox())
  232.  
  233.         # Read and Set Plugin Version
  234.         self.pluginVersion = self.get_num(self.readFileAndFindString(self.plugin_dir + '/metadata.txt', 'version='))
  235.  
  236.     def unload(self):
  237.         """Removes the plugin menu item and icon from QGIS GUI."""
  238.         for action in self.actions:
  239.             self.iface.removePluginMenu(
  240.                 self.tr(u'&RimoPrinting'),
  241.                 action)
  242.             self.iface.removeToolBarIcon(action)
  243.         # remove the toolbar
  244.         del self.toolbar
  245.  
  246. #############
  247. # Run Method:
  248. #############
  249.  
  250.     def run(self):
  251.         # Set Global Variables (For tasks without Login)
  252.         self.setGlobalVariables()
  253.  
  254.         """Run method that performs all the real work"""
  255.         # show the dialog
  256.         #if self.dlgIsActive == True:
  257.         #    self.dlg.show()
  258.         #    return
  259.  
  260.         self.dlg.show()
  261.         self.dlgIsActive = True
  262.  
  263.         # Run the dialog event loop
  264.         result = self.dlg.exec_()
  265.  
  266.         #Run if Cancel is pressed
  267.         if result == 0:
  268.             return
  269.  
  270.         # See if OK was pressed
  271.         if result:
  272.             self.iface.messageBar().clearWidgets()
  273.             self.iface.messageBar().pushInfo("RimoPrinting:", "Preparing Data Structure...")
  274.             if self.checkIfEmptyProject() == True:
  275.                 if self.createDataDir() == True:
  276.                     if self.createRevisionCSV() == True:
  277.                         self.iface.messageBar().clearWidgets()
  278.                         self.iface.messageBar().pushInfo("RimoPrinting:", "Loading Rimo Data...")
  279.                         if self.loadData() == True:
  280.                             self.iface.messageBar().clearWidgets()
  281.                             self.iface.messageBar().pushInfo("RimoPrinting:", "Loading Revision CSV...")
  282.                             if self.loadRevisionCSV() == True:
  283.                                 if self.setCRSToEPSG31256() == True:
  284.                                     self.iface.messageBar().clearWidgets()
  285.                                     self.iface.messageBar().pushInfo("RimoPrinting:", "Data has been successfully loaded!")
  286.                                     self.saveCurrentProject()
  287.             return
  288.  
  289.  
  290. ##############
  291. # Gui Methods:
  292. ##############
  293.  
  294.     # Login
  295.     def login(self, rimoUrl, user, password):
  296.         global project
  297.  
  298.         # Rimo Url
  299.         if rimoUrl == 'Production':
  300.             self.rimoUrl = "https://rimo-saas.com/"
  301.             project.writeEntry("rP", "rimoUrl", "https://rimo-saas.com/")
  302.  
  303.         else:
  304.             self.rimoUrl = "https://rimo-dev.rimo-saas.com/"
  305.             project.writeEntry("rP", "rimoUrl", "https://rimo-dev.rimo-saas.com/")
  306.  
  307. #        # Check for Proxy
  308. #        s = QSettings()
  309. #        proxyEnabled = s.value("proxy/proxyEnabled", "")
  310. #        print(proxyEnabled)
  311. #        if proxyEnabled == "true":
  312. #            proxyType = str(s.value("proxy/proxyType", "" ))
  313. #            proxyHost = str(s.value("proxy/proxyHost", "" ))
  314. #            proxyPort = str(s.value("proxy/proxyPort", "" ))
  315. #            proxyUser = str(s.value("proxy/proxyUser", "" ))
  316. #            proxyPassword = str(s.value("proxy/proxyPassword", "" ))
  317. #            proxyPrefix = str(proxyHost.split(':')[0])
  318. #            proxyUrl = str(proxyHost.split(':')[1][2:])
  319. #            userAndPass = ""
  320. #            if proxyPassword:
  321. #                userAndPass = proxyUser + ":" + proxyPassword + "@"
  322. #
  323. #            proxyNewUrl = proxyPrefix + "://" + userAndPass + proxyUrl + ":" + proxyPort
  324. #            self.proxieSettings = {proxyPrefix: proxyNewUrl}
  325. #
  326. #
  327. #        else:
  328. #            self.proxieSettings = {"http": self.rimoUrl}
  329.  
  330.         # Login Request
  331.         r = requests.post(self.rimoUrl + "api/MIT/SDMeteorQGISController/", data=json.dumps({"method": "verifyUser", "user": user, "password": password}))
  332.  
  333.         data = json.loads(r.text)
  334.         if "_error" in data:
  335.             self.renderWarning("Wrong Username or Password")
  336.             return False
  337.         if "asOop" in data:
  338.             # Tenant Stuff
  339.             tenants = data["userProfile"]
  340.             self.loginStatus = True
  341.             self.dlg.label_10.setText("Logged In.")
  342.             self.dlg.pushButton.setEnabled(False)
  343.             self.dlg.lineEdit.setEnabled(False)
  344.             self.dlg.lineEdit_2.setEnabled(False)
  345.             self.dlg.comboBox_8.setEnabled(False)
  346.             self.dlg.pushButton_2.setEnabled(True)
  347.             self.dlg.comboBox_4.setEnabled(True)
  348.             self.tenants = tenants
  349.             tenantList = []
  350.             for t in self.tenants:
  351.                 tenantList.append(t["tenant"]["id"])
  352.             self.dlg.comboBox_4.addItems(tenantList)
  353.  
  354.     # Select Tenant
  355.     def selectTenant(self, tenantOop, tenantId):
  356.         global project
  357.         self.dlg.pushButton_2.setEnabled(False)
  358.         self.dlg.comboBox_4.setEnabled(False)
  359.  
  360.         #Global TenantOop
  361.         self.tenantOop = tenantOop
  362.         project.writeEntry("rP", "tenantOop", str(tenantOop))
  363.  
  364.         #Global TenantID
  365.         self.tenantId = str(tenantId)
  366.         project.writeEntry("rP", "tenantId", str(tenantId))
  367.  
  368.         #Global UserOop
  369.         self.userOop = [x for x in self.tenants if x["tenant"]["asOop"] == self.tenantOop][0]["asOop"]
  370.         project.writeEntry("rP", "userOop", str(self.userOop))
  371.  
  372.         #Disable loginButton
  373.         self.dlg.pushButton.setEnabled(False)
  374.         self.disableLoginAndTenantGui(True)
  375.         #Populate ComboBoxen
  376.         #Regions ComboBox
  377.         self.regionData()
  378.         #Cluster ComboBox
  379.         self.clusterData()
  380.         #SiteCluster ComboBox
  381.         self.siteClusterData()
  382.         return True
  383.  
  384.  
  385. ####################
  386. # Gui Helper Methods
  387. ####################
  388.  
  389.     # Disable Login And Tenant Gui Fields
  390.     def disableLoginAndTenantGui(self, status):
  391.         elements = [
  392.             self.dlg.comboBox,
  393.             self.dlg.comboBox_2,
  394.             self.dlg.comboBox_3,
  395.             self.dlg.button_box
  396.         ]
  397.  
  398.         for e in elements:
  399.             e.setEnabled(status)
  400.  
  401.     # Load Region Data
  402.     def regionData(self):
  403.         try:
  404.             self.getRimoData(self.rimoUrl + "api/MIT/SDMeteorQGISController", "getRegionsFromTenant", self.tenantOop, "nameToDisplay", self.dlg.comboBox, "regionData")
  405.         except:
  406.             pass
  407.         self.dlg.comboBox.activated.connect(lambda: self.comboBoxChange())
  408.  
  409.     # Load Cluster Data
  410.     def clusterData(self):
  411.         try:
  412.             self.getRimoData(self.rimoUrl + "api/MIT/SDMeteorQGISController", "getClustersFromRegion", self.dataStore["regionData"][self.dlg.comboBox.currentIndex()]['asOop'], "nameToDisplay", self.dlg.comboBox_2, "clusterData")
  413.         except:
  414.             pass
  415.         self.dlg.comboBox_2.activated.connect(lambda: self.comboBox_2Change())
  416.  
  417.     # Load Site Cluster Data
  418.     def siteClusterData(self):
  419.         try:
  420.             self.getRimoData(self.rimoUrl + "api/MIT/SDMeteorQGISController", "getSiteClustersFromClusters", self.dataStore["clusterData"][self.dlg.comboBox_2.currentIndex()]['asOop'], "nameToDisplay", self.dlg.comboBox_3, "siteClusterData")
  421.         except:
  422.  
  423.             pass
  424.         self.dlg.comboBox_3.activated.connect(lambda: self.comboBox_3Change())
  425.  
  426.     # Access Rimo Data (Used By SiteCluster, Cluster and Region Methods)
  427.     def getRimoData(self, url, method, Oop, comboParameter, comboBox, store):
  428.         #Clear ComboBox
  429.         comboBox.clear()
  430.  
  431.         #Load and Parse Data
  432.         r = requests.post(url, data =json.dumps({'method': method, 'Oop': Oop, 'version': self.pluginVersion, 'userOop': self.userOop}))
  433.         data = json.loads(r.text)
  434.  
  435.         #Create Content
  436.         myList = []
  437.         if store == "siteClusterData":
  438.             myList.append("Whole Cluster")
  439.         if len(data) > 0:
  440.             for e in data:
  441.                 myList.append(e[comboParameter])
  442.  
  443.             #setNewDataStorage
  444.             dataStorage = data
  445.         else:
  446.             self.dataStorage = []
  447.  
  448.         #Return List
  449.         comboBox.addItems(myList)
  450.  
  451.         #Data
  452.         self.dataStore[store] = data
  453.  
  454.     # Events fired when comboBox Changes (RegionData)
  455.     def comboBoxChange(self):
  456.         self.dlg.comboBox_3.clear()
  457.         self.dlg.comboBox_3.activated.disconnect()
  458.         self.dlg.comboBox_2.clear()
  459.         self.dlg.comboBox_2.activated.disconnect()
  460.         #Reload Content
  461.         self.clusterData()
  462.         self.siteClusterData()
  463.  
  464.     # Events fired when comboBox_2 Changes (ClusterData)
  465.     def comboBox_2Change(self):
  466.         self.dlg.comboBox_3.clear()
  467.         self.dlg.comboBox_3.activated.disconnect()
  468.         #Reload Content
  469.         self.siteClusterData()
  470.  
  471.     # Events fired when comboBox_3 Changes (SiteClusterData)
  472.     def comboBox_3Change(self):
  473.         return
  474.  
  475.  
  476. ######################
  477. # Data loading Methods
  478. ######################
  479.  
  480.     # Check Cluster Has Data
  481.     def checkIfClusterHasData(self, selection):
  482.         if selection == "" or selection == "No Data available":
  483.             return False
  484.         return True
  485.  
  486.     # Check If Layer Group Exists
  487.     def checkIfLayerGroupExists(self, layerGroupName):
  488.         for child in self.layerTree.children():
  489.             if isinstance(child, QgsLayerTreeGroup):
  490.                 if child.name() == layerGroupName:
  491.                     return True
  492.         return False
  493.  
  494.     # Check If Layer Exists
  495.     def checkIfLayerExists(self, layerMetaData):
  496.         layers = self.iface.legendInterface().layers()
  497.         for layer in layers:
  498.             if layer.keywordList() != "":
  499.                 layerName = json.loads(layer.keywordList())["name"]
  500.                 if layerName == layerMetaData["name"]:
  501.                     return True
  502.         return False
  503.  
  504.     # Get Rimo Layer Properties
  505.     def getRimoLayerProperties(self):
  506.         rimoLayerProps = [
  507.             {"path": "exportBuildingsToGeoJson", "name": "Buildings", "selected": True},
  508.             {"path": "exportFCPsToGeoJson", "name": "FCPs", "selected": True},
  509.             {"path": "exportAccessNodesToGeoJson", "name": "Access Nodes", "selected": True},
  510.             {"path": "exportRouteLocationsToGeoJson", "name": "Route Locations", "selected": True},
  511.             {"path": "exportDirectionLinesToGeoJson", "name": "Direction Lines", "selected": True},
  512.             {"path": "exportShaftLocationsToGeoJson", "name": "Shaft Locations", "selected": True},
  513.             {"path": "exportTrenchesToGeoJson", "name": "Trenches", "selected": True},
  514.             {"path": "exportPipesToGeoJson", "name": "Pipes", "selected": False},
  515.             {"path": "exportCladdingPipesToGeoJson", "name": "Cladding Pipes", "selected": False},
  516.             {"path": "exportInfoLocationsToGeoJson", "name": "Info Locations", "selected": True},
  517.             {"path": "exportFCPPolygonsToGeoJson", "name": "FCP Polygons", "selected": True},
  518.             {"path": "exportSiteClusterPolygonsToGeoJson", "name": "SiteCluster Polygons", "selected": True},
  519.             {"path": "exportClusterPolygonsToGeoJson", "name": "Cluster Polygons", "selected": False}
  520.         ]
  521.         return rimoLayerProps
  522.    
  523.     # Get Backbone Layer Properties
  524.     def getBackboneRegionLayerProperties(self):
  525.         backboneRegionLayerProps = [
  526.             {"path": "exportClusterPolygonsToGeoJson", "name": "Backbone Cluster Polygons", "selected": False},
  527.             {"path": "exportSiteClusterToGeoJson", "name": "Backbone Site Cluster ", "selected": False},
  528.             {"path": "exportAccessNodesToGeoJson", "name": "Backbone POP", "selected": False},
  529.             {"path": "exportBackboneConnectionsToGeoJson", "name": "Backbone Connection", "selected": False},
  530.             {"path": "exportTrenchesToGeoJson", "name": "Backbone Trenches", "selected": False},
  531.             {"path": "exportCablesToGeoJson", "name": "Backbone Cables", "selected": False},
  532.             {"path": "exportPipesToGeoJson", "name": "Backbone Pipes", "selected": False}
  533.         ]
  534.         return backboneRegionLayerProps
  535.  
  536.     # Get WMS Layer Properties
  537.     def getWmsLayerProperties(self):
  538.         wmsLayerProps = [
  539.             {"path": "contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=basemap_grau_layer&styles=&url=http://tileserver.rimo-saas.com:8081/service?", "name": "Geoland Basemap Grau", "selected": True},
  540.             {"path": "contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=basemap_layer&styles=&url=http://tileserver.rimo-saas.com:8081/service?", "name": "Geoland Basemap", "selected": False},
  541.             {"path": "contextualWMSLegend=0&crs=EPSG:4326&dpiMode=7&featureCount=10&format=image/png&layers=INSPIRE.KA_GRUNDSTUECK&styles=&url=http://tileserver.rimo-saas.com:8081/service?", "name": "DKM", "selected": True}
  542.         ]
  543.         return wmsLayerProps
  544.  
  545.     # Add Layer To Iface
  546.     def addLayer(self, layerType, Oop, layerProps, currentGroup):
  547.         if layerType == "Rimo":
  548.             layer = QgsVectorLayer(self.rimoUrl + "geo/" + self.tenantId + "/" + str(Oop) + "/" + layerProps["path"], layerProps["name"], "ogr")
  549.             layer.setKeywordList('{"type": "RimoLayer", "name": "' + layerProps['name'] + '"}')
  550.         elif layerType == "Wms":
  551.             layer = QgsRasterLayer(layerProps["path"], layerProps["name"], "wms")
  552.             layer.setKeywordList('{"type": "WmsLayer", "name": "' + layerProps['name'] + '"}')
  553.  
  554.         # Set Style from style Sheet
  555.         self.setStyle(layer, layerProps["name"])
  556.  
  557.         # Add the layer to the registry, False indicates not to add to the layer tree
  558.         QgsMapLayerRegistry.instance().addMapLayer(layer, False)
  559.  
  560.         # Append layer to the root group node
  561.         currentGroup.addLayer(layer)
  562.  
  563.         # Set Layer Visible / not Visible
  564.         self.iface.legendInterface().setLayerVisible(layer, layerProps["selected"])
  565.  
  566.     # Set Layer Styling
  567.     def setStyle(self, layer, qmlName):
  568.         layer.loadNamedStyle(self.plugin_dir + '/styles/default/' + qmlName + '.qml')
  569.  
  570.  
  571.     # Set Styling of Folder
  572.     def setStylingForLayerOfMatchingQMLFiles(self, fileName, path):
  573.         layer = self.getLayerByName(fileName)
  574.         if layer != False:
  575.             layer.loadNamedStyle(path)
  576.  
  577.  
  578. ##################
  579. # Methods when Run
  580. ##################
  581.  
  582.     # Check If Project Is Empty
  583.     def checkIfEmptyProject(self):
  584.         if self.checkIfProjectHasDataLayer() == True or self.checkIfProjectHasPrintComposer() == True:
  585.             self.renderWarning("There is already Data or at least one print composer in this Project - Please use an empty QGis-Project for Data loading!")
  586.             return False
  587.         return True
  588.  
  589.     # Create Data Dir
  590.     def createDataDir(self):
  591.         global project
  592.         if self.isDev():
  593.             folderP = "Development_" + self.tenantId + "_" + unicode(self.dlg.comboBox.currentText()) + "_" + unicode(self.dlg.comboBox_2.currentText()) + "_" + unicode(self.dlg.comboBox_3.currentText()) + "_" + str(time.time())[:-3]
  594.         else:
  595.             folderP = self.tenantId + "_" + unicode(self.dlg.comboBox.currentText()) + "_" + unicode(self.dlg.comboBox_2.currentText()) + "_" + unicode(self.dlg.comboBox_3.currentText()) + "_" + str(time.time())[:-3]
  596.  
  597.         dataDirectory = self.plugin_dir + "/Data/" + folderP
  598.         self.dataDirectory = dataDirectory
  599.         project.writeEntry("rP", "dataDirectory", self.dataDirectory)
  600.         self.folderPathURLEncoded = urllib.quote(folderP.encode('utf8'))
  601.         project.writeEntry("rP", "folderPathURLEncoded",  urllib.quote(folderP.encode('utf8')))
  602.  
  603.         if not os.path.exists(self.dataDirectory):
  604.             os.makedirs(self.dataDirectory)
  605.             return True
  606.         return False
  607.  
  608.     # Create A Revision CSV (Important for Composer)
  609.     def createRevisionCSV(self):
  610.         try:
  611.             csvFile = self.dataDirectory + "/revision.csv"
  612.             with open(csvFile, 'w') as csvfile:
  613.                 fieldnames = ['Revision:', 'Bearbeiter:', 'Kommentar:']
  614.                 writer = csv.writer(csvfile, delimiter=';', lineterminator='\n', quotechar='"', quoting=csv.QUOTE_MINIMAL)
  615.                 writer.writerow(fieldnames)
  616.                 row1 = ['1', '', '']
  617.                 writer.writerow(row1)
  618.             return True
  619.         except:
  620.             return False
  621.  
  622.     # Load WMS and Rimo Data
  623.     def loadData(self):
  624.         global project
  625.         selection = self.dlg.comboBox_3.currentText()
  626.         if self.checkIfClusterHasData(selection) == False:
  627.             self.renderWarning("No Data for this Cluster available")
  628.             return
  629.  
  630.         # Get Oop for Rest Call / Set Grid Layer
  631.         if selection == "Whole Cluster":
  632.             Oop = self.dataStore["clusterData"][self.dlg.comboBox_2.currentIndex()]['asOop']
  633.  
  634.         else:
  635.             Oop = self.dataStore["siteClusterData"][self.dlg.comboBox_3.currentIndex() - 1]['asOop']
  636.  
  637.         # Set Global Variab+les
  638.         self.clusterOop = str(Oop)
  639.         project.writeEntry("rP", "clusterOop", str(Oop))
  640.         self.regionName = self.dlg.comboBox.currentText()
  641.         project.writeEntry("rP", "regionName", unicode(self.regionName))
  642.         self.clusterName = self.dlg.comboBox_2.currentText()
  643.         project.writeEntry("rP", "clusterName", unicode(self.clusterName))
  644.         self.siteClusterName = self.dlg.comboBox_3.currentText()
  645.         project.writeEntry("rP", "siteClusterName", unicode(self.siteClusterName))
  646.  
  647.         # Load RimoLayer & Wms Layer Settings
  648.         rimoLayerProps = self.getRimoLayerProperties()
  649.         wmsLayerProps = self.getWmsLayerProperties()
  650.  
  651.         # Create Layer Group For Rimo Layer in Iface
  652.         self.currentGroup = self.layerTree.addGroup(self.tenantId + ", " + unicode(self.dlg.comboBox.currentText()) + ", " + unicode(self.dlg.comboBox_2.currentText()) + ", " + unicode(self.dlg.comboBox_3.currentText()))
  653.  
  654.         # Load RimoLayer
  655.         for l in rimoLayerProps:
  656.             try:
  657.                 self.addLayer("Rimo", Oop, l, self.currentGroup)
  658.             except:
  659.                 self.renderWarning("No Data for Layer: " + l["name"])
  660.  
  661.         # Create LayerGroup for Overlaymaps / Basemaps if it does not exist
  662.         if self.checkIfLayerGroupExists("Overlaymaps / Basemaps") == False:
  663.             self.layerTree.addGroup(unicode("Overlaymaps / Basemaps"))
  664.  
  665.         # Add Layer to Overlaymaps / Basemaps - LayerGroup
  666.         for l in wmsLayerProps:
  667.             if self.checkIfLayerExists(l) == False:
  668.                     self.addLayer("Wms", None, l, self.layerTree.findGroup(unicode("Overlaymaps / Basemaps")))
  669.  
  670.  
  671.         # Set Grid Layer
  672.         if selection == "" or selection == "No Data available":
  673.             return
  674.         elif selection == "Whole Cluster":
  675.             for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
  676.                 if lyr.name() == "Cluster Polygons":
  677.                     layername = lyr.name()
  678.         else:
  679.             for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
  680.                 if lyr.name() == "SiteCluster Polygons":
  681.                     layername = lyr.name()
  682.  
  683.         # Set Global Variable
  684.         self.gridLayerName = layername
  685.         project.writeEntry("rP", "gridLayerName", layername)
  686.  
  687.         # Add GridGroup to Legend
  688.         self.gridGroup = self.currentGroup.addGroup("Grids")
  689.  
  690.         # Add BackboneGroup to Legend
  691.         self.backboneRegionGroup = self.layerTree.addGroup("Backbone Data")
  692.  
  693.         # Check if 'Backbone Region Data' is selected and load backbone data if so
  694.         if self.dlg.checkBox.checkState() != 0:
  695.             self.loadBackboneRegionData()
  696.  
  697.  
  698.         return True
  699.  
  700.     # Load Revision CSV
  701.     def loadRevisionCSV(self):
  702.         csvUri = "file:///" + self.plugin_dir + "/Data/" + self.folderPathURLEncoded + "/revision.csv" + "?delimiter=;&encoding=WINSAMI2"
  703.         csvLayer = QgsVectorLayer(csvUri, "Revision", "delimitedtext")
  704.         csvLayer.setKeywordList('{"type": "RimoLayer", "name": "revision"}')
  705.         QgsMapLayerRegistry.instance().addMapLayer(csvLayer, False)
  706.         self.currentGroup.addLayer(csvLayer)
  707.         self.iface.legendInterface().setLayerVisible(csvLayer, True)
  708.         return True
  709.  
  710.     # Set CRS
  711.     def setCRSToEPSG31256(self):
  712.         if self.iface.mapCanvas().mapRenderer().hasCrsTransformEnabled():
  713.             my_crs = QgsCoordinateReferenceSystem(31256, QgsCoordinateReferenceSystem.EpsgCrsId)
  714.             self.iface.mapCanvas().mapRenderer().setDestinationCrs(my_crs)
  715.             self.iface.mapCanvas().setMapUnits(0)
  716.             self.iface.mapCanvas().refresh()
  717.             return True
  718.  
  719.     # Load BackboneRegion Data
  720.     def loadBackboneRegionData(self):
  721.         global project
  722.  
  723.         # Load BackboneRegionLayer Settings
  724.         backboneLayerProps = self.getBackboneRegionLayerProperties()
  725.  
  726.         # Get BackboneLayerGroup
  727.         self.backboneGroup = self.getBackboneGroup()
  728.         if self.backboneGroup == False:
  729.             self.backboneGroup = self.layerTree.addGroup("Backbone Data")
  730.  
  731.         # Check if there is already Data in Group
  732.         if self.getAmountOfChildrenInGroup(self.backboneGroup) > 0:
  733.             self.renderWarning("Data has already been loaded in Backbone Data Group - Use Update Rimo Layer instead")
  734.             return False
  735.  
  736.         # Get Backbone Region Oop
  737.         self.backboneRegionOop = self.getBackboneRegionOop(self.clusterOop)
  738.         print self.clusterOop
  739.         if self.backboneRegionOop == False:
  740.             self.renderWarning("There are problems loading Backbone Data - Please contact the admin!")
  741.             return False
  742.  
  743.         # Load BackboneRegionLayer
  744.         for l in backboneLayerProps:
  745.             try:
  746.                 self.addLayer("Rimo", self.backboneRegionOop, l, self.backboneGroup)
  747.             except:
  748.                 self.renderWarning("No Data for Layer: " + l["name"])
  749.  
  750.         return True
  751.  
  752.     # Change Layer Styles
  753.     def changeLayerStyles(self):
  754.         styling = self.dlg.comboBox_9.currentText()
  755.         path = self.plugin_dir + "/styles/" + styling
  756.         for myFile in (os.listdir(path)):
  757.             self.setStylingForLayerOfMatchingQMLFiles(os.path.splitext(myFile)[0], path + "/" + myFile)
  758.         self.iface.mapCanvas().refresh()
  759.         self.iface.mapCanvas().refreshAllLayers()
  760.         return
  761.  
  762.  
  763. ###############################
  764. # Print Composer Helper Methods
  765. ###############################
  766.  
  767.     # Get Grid Layer values
  768.     def getGridLayerValues(self, cFormat, cScale):
  769.         if cFormat == "A0" and cScale == "500":
  770.             M = [{"value": 350, "selected": False, "format": "A0", "scale": "500"}]
  771.  
  772.         if cFormat == "A0" and cScale == "1000":
  773.             M = [{"value": 700, "selected": False, "format": "A0", "scale": "1000"}]
  774.  
  775.         if cFormat == "A1" and cScale == "500":
  776.             M = [{"value": 250, "selected": False, "format": "A1", "scale": "500"}]
  777.  
  778.         if cFormat == "A1" and cScale == "1000":
  779.             M = [{"value": 500, "selected": False, "format": "A1", "scale": "1000"}]
  780.  
  781.         if cFormat == "A2" and cScale == "500":
  782.             M = [{"value": 180, "selected": False, "format": "A2", "scale": "500"}]
  783.  
  784.         if cFormat == "A2" and cScale == "1000":
  785.             M = [{"value": 370, "selected": False, "format": "A2", "scale": "1000"}]
  786.  
  787.         if cFormat == "A3" and cScale == "500":
  788.             M = [{"value": 130, "selected": False, "format": "A3", "scale": "500"}]
  789.  
  790.         if cFormat == "A3" and cScale == "1000":
  791.             M = [{"value": 250, "selected": True, "format": "A3", "scale": "1000"}]
  792.  
  793.         if cFormat == "A4" and cScale == "500":
  794.             M = [{"value": 100, "selected": False, "format": "A4", "scale": "500"}]
  795.  
  796.         if cFormat == "A4" and cScale == "1000":
  797.             M = [{"value": 100, "selected": False, "format": "A4", "scale": "1000"}]
  798.  
  799.         return M
  800.  
  801.  
  802.     # Creates Atlas Grids
  803.     def createAtlasGrid(self, inputLayer, currentGroup, M):
  804.         global project
  805.         # Calculate Layer in MGI
  806.         inputLayerMGI = processing.getObject(processing.runalg("qgis:reprojectlayer", inputLayer, "EPSG:31256", None)['OUTPUT'])
  807.  
  808.         # Calculate Center Point
  809.         centroidLayer = processing.getObject(processing.runalg("qgis:polygoncentroids", inputLayerMGI, None)['OUTPUT_LAYER'])
  810.         for feat in centroidLayer.getFeatures():
  811.             x = feat.geometry().asPoint()
  812.  
  813.         # Calculate Boundings
  814.         boundingPolygon = processing.getObject(processing.runalg("qgis:polygonfromlayerextent", inputLayerMGI, False, None)['OUTPUT'])
  815.         for feat in boundingPolygon.getFeatures():
  816.             XMIN = feat.attributes()[0]
  817.             YMIN = feat.attributes()[1]
  818.             XMAX = feat.attributes()[2]
  819.             YMAX = feat.attributes()[3]
  820.  
  821.         for m in M:
  822.             # Recalculate XMAX - XMIN
  823.             if((XMAX - XMIN) < m["value"]):
  824.                 add = (m["value"] - (XMAX - XMIN)) / 2
  825.                 XMAX = XMAX + add
  826.                 XMIN = XMIN - add
  827.                
  828.             if((YMAX - YMIN) < m["value"]):
  829.                 add = (m["value"] - (YMAX - YMIN)) / 2
  830.                 YMAX = YMAX + add
  831.                 YMIN = YMIN - add
  832.                
  833.                
  834.             # Calculate Distance & New Boundings
  835.             EW = XMAX - XMIN
  836.             NS = YMAX - YMIN
  837.             aEW = (EW % 10) / 2
  838.             aNS = (NS % 10) / 2
  839.  
  840.             nXMIN = XMIN - aEW
  841.             nYMIN = YMIN - aNS
  842.             nXMAX = XMAX + aEW
  843.             nYMAX = YMAX + aNS
  844.  
  845.             fieldAmountEW = int((nXMAX - nXMIN) / m["value"])
  846.             fieldAmountNS = int((nYMAX - nYMIN) / m["value"])
  847.  
  848.             extent = str(nXMIN) + ", " + str(nXMAX) + ", " + str(nYMIN) + ", " + str(nYMAX)
  849.  
  850.             # Create Grid
  851.             grid = processing.getObject(processing.runalg("qgis:creategrid", 1, extent, m["value"], m["value"], "EPSG:31256", None)['OUTPUT'])
  852.             gridWGS = processing.getObject(processing.runalg("qgis:reprojectlayer", grid, "EPSG:4326", None)['OUTPUT'])
  853.  
  854.             # Check if Polygon is in Feature Grid + Add Attribute
  855.             finalGrid = processing.getObject(processing.runalg("qgis:joinattributesbylocation", gridWGS, self.getLayerByTagName("Trenches"),u'intersects',0,1,"mean",1,None)['OUTPUT'])
  856.             finalGrid = processing.getObject(processing.runalg("qgis:joinattributesbylocation", finalGrid, self.getLayerByTagName("Buildings"),u'intersects',0,1,"mean",1,None)['OUTPUT'])
  857.             gridName = str(m["format"]) + "_" + str(m["scale"]) + '_Grid_' + str(m["value"]) + 'm'
  858.  
  859.             if self.getLayerByTagName(gridName) != False:
  860.                 return gridName
  861.  
  862.             finalGrid.setLayerName(gridName)
  863.  
  864.             # Add Column for Intersection
  865.             finalGrid.dataProvider().addAttributes([QgsField("data_in_g", QVariant.Int)])
  866.             finalGrid.updateFields()
  867.  
  868.             # Calculate Value
  869.             data_in_gIdx = finalGrid.fieldNameIndex('data_in_g')
  870.             countIdx = finalGrid.fieldNameIndex('count')
  871.             count_1Idx = finalGrid.fieldNameIndex('count_1')
  872.             attrFeatMap = {}
  873.             for feature in finalGrid.getFeatures():
  874.                 #Fill data_in_g Column
  875.                 if feature.attributes()[countIdx] or feature.attributes()[count_1Idx]:
  876.                     attrFeatMap[ feature.id() ] = { data_in_gIdx : 1 }
  877.                 else:
  878.                     attrFeatMap[ feature.id() ] = { data_in_gIdx : 0 }
  879.  
  880.             finalGrid.dataProvider().changeAttributeValues(attrFeatMap)
  881.  
  882.             #Create FieldNames
  883.             #Create Numbers for Atlas
  884.             #Add ID Column
  885.             finalGrid.dataProvider().addAttributes([QgsField("ID", QVariant.Int)])
  886.             finalGrid.dataProvider().addAttributes([QgsField("Page", QVariant.String)])
  887.             finalGrid.updateFields()
  888.             idIDX = finalGrid.fieldNameIndex("ID")
  889.             pageIDX = finalGrid.fieldNameIndex("Page")
  890.  
  891.  
  892.             #Calculate IDs
  893.             count = 0
  894.             finalGrid.startEditing()
  895.             for feature in finalGrid.getFeatures():
  896.                 finalGrid.changeAttributeValue(feature.id(), idIDX, count)
  897.                 count = count + 1
  898.  
  899.             #Sort IDs
  900.             featureList = []
  901.             for feature in finalGrid.getFeatures():
  902.                 myValue = feature.attributes()
  903.                 appendValue = [0 if isinstance(v, QPyNullVariant) else v for v in myValue]
  904.                 featureList.append(appendValue)
  905.  
  906.             featureList.sort(key=lambda x: x[1], reverse=True)
  907.  
  908.             #Fill ID Column
  909.             count = 0
  910.             row = 0
  911.             column = 0
  912.             fieldAmountEW = fieldAmountEW + 1
  913.             for feature in featureList:
  914.                 finalGrid.changeAttributeValue(feature[idIDX], idIDX, count)
  915.                 if count > 1:
  916.                     if count % fieldAmountEW == 0:
  917.                         row = row + 1
  918.                         column = 0
  919.  
  920.                 pageName = str(row) + '--' + str(column)
  921.                 finalGrid.changeAttributeValue(feature[idIDX], pageIDX, pageName)
  922.                 count = count + 1
  923.                 column = column + 1
  924.  
  925.  
  926.  
  927.             finalGrid.commitChanges()
  928.  
  929.             # Create /Remove Shapefile
  930.             shpPath = self.dataDirectory + "/" + gridName
  931.  
  932.             # Remove Shapefile if Exists
  933.             self.removeShapefileIfExists(gridName)
  934.  
  935.             # Create Shapefile and add it to canvas
  936.             QgsVectorFileWriter.writeAsVectorFormat(finalGrid, shpPath, "utf-8", None, "ESRI Shapefile")
  937.  
  938.             layer = QgsVectorLayer(shpPath + ".shp", gridName, "ogr")
  939.             layer.setKeywordList('{"type": "GridLayer", "name": "' + gridName + '"}')
  940.             QgsMapLayerRegistry.instance().addMapLayer(layer, False)
  941.  
  942.             # Set Style
  943.             self.setStyle(layer, layer.name())
  944.  
  945.             # Set Layer Visible / not Visible
  946.             self.iface.legendInterface().setLayerVisible(layer, m["selected"])
  947.  
  948.             # Add Layer to Root Group
  949.             currentGroup.addLayer(layer)
  950.  
  951.         return gridName
  952.  
  953.     # Check if there has been Rimo Data added at least once
  954.     def checkIfThereIsRimoData(self):
  955.         if self.gridLayerName == "nothing":
  956.             return False
  957.         return True
  958.  
  959.     # Get Filepath of Composer Template File
  960.     def getPrintComposerTemplateFile(self, filename):
  961.         myFile = os.path.dirname(os.path.dirname(os.path.dirname(self.plugin_dir))) + "/composer_templates/" + filename + ".qpt"
  962.         if self.checkIfPathExists(myFile):
  963.             return myFile
  964.         else:
  965.             return False
  966.  
  967.     # Get Rimo Composer Data
  968.     def getRimoComposerData(self, tenantId, clusterOop):
  969.         global project
  970.         url = self.rimoUrl + "geo/" + self.tenantId + "/" + self.clusterOop + "/exportMetaInfo"
  971.         r = requests.get(url)
  972.         return json.loads(r.text)
  973.  
  974.     # Create New Composer File
  975.     def createNewRimoComposer(self, cScale, cFormat, atlasGrid, createAtlas):
  976.         global project
  977.         # Create CRS Transformation for Grids
  978.         transform = self.crsTransformation(4326, 31256)
  979.         # Get Map Canvas
  980.         canvas = QgsMapCanvas()
  981.  
  982.         if createAtlas == "Atlas":
  983.             # Set Composer Name
  984.             cN = "Atlas" + "_" + str(cFormat) + "_" + str(cScale)
  985.  
  986.         if createAtlas == "Individual":
  987.             # Set Composer Name
  988.             cN = "Individual" + "_" + str(cFormat) + "_" + str(cScale)
  989.  
  990.         if createAtlas == "Atlas_StaticLegend":
  991.             # Set Composer Name
  992.             cN = "Atlas_StaticLegend" + "_" + str(cFormat) + "_" + str(cScale)
  993.  
  994.         # Load Composer File
  995.         myFile = self.getPrintComposerTemplateFile(cN)
  996.         if myFile == False:
  997.             self.renderWarning("No print composer template for the chosen scale / format found.")
  998.             return
  999.  
  1000.  
  1001.         myTemplateFile = file(myFile, 'rt')
  1002.         myTemplateContent = myTemplateFile.read()
  1003.         myTemplateFile.close()
  1004.  
  1005.         # Create Document from File
  1006.         myDocument = QDomDocument()
  1007.         myDocument.setContent(myTemplateContent, False)
  1008.  
  1009.         # Create Composer in Iface
  1010.         self.composer = self.iface.createNewComposer(cN)
  1011.         self.composer.composition().loadFromTemplate(myDocument)
  1012.         self.composition = QgsComposition(self.iface.mapCanvas().mapSettings())
  1013.         self.composition.refreshItems()
  1014.         self.myComposition = self.composer.composition()
  1015.  
  1016.  
  1017.         # Get Data From Template
  1018.         # Get Maps
  1019.         mainMap = self.myComposition.getComposerItemById('mainMap')
  1020.         mainMap.setMapCanvas(canvas)
  1021.         overviewMap = self.myComposition.getComposerItemById('overviewMap')
  1022.         overviewMap.setMapCanvas(canvas)
  1023.  
  1024.         # Get Frames
  1025.         planartFrame = self.myComposition.getComposerItemById('planartFrame')
  1026.         regionFrame = self.myComposition.getComposerItemById('regionFrame')
  1027.         parentFrame = self.myComposition.getComposerItemById('parentFrame')
  1028.         bauabschnittFrame = self.myComposition.getComposerItemById('bauabschnittFrame')
  1029.         bereichsbezeichnungFrame = self.myComposition.getComposerItemById('bereichsbezeichnungFrame')
  1030.  
  1031.         # Get Frame-Text
  1032.         planartFrameText = self.myComposition.getComposerItemById('planartFrameText')
  1033.         regionFrameText = self.myComposition.getComposerItemById('regionFrameText')
  1034.         parentFrameText = self.myComposition.getComposerItemById('parentFrameText')
  1035.         bauabschnittFrameText = self.myComposition.getComposerItemById('bauabschnittFrameText')
  1036.         bereichsbezeichnungFrameText = self.myComposition.getComposerItemById('bereichsbezeichnungFrameText')
  1037.         datumFrameText = self.myComposition.getComposerItemById('datumFrameText')
  1038.  
  1039.         # Get Impressum
  1040.         impressum =  self.myComposition.getComposerItemById('Anschrift')
  1041.  
  1042.         # Get Tables
  1043.         revisionTable = self.myComposition.getComposerItemById('revisionTable').multiFrame()
  1044.  
  1045.         # Get Logos
  1046.         companyLogo = self.myComposition.getComposerItemById('companyLogo')
  1047.  
  1048.         # Get Legend
  1049.         legendFrame = self.myComposition.getComposerItemById('legendFrame')
  1050.         legend = self.myComposition.getComposerItemById('legend')
  1051.  
  1052.         # Get NorthArrow
  1053.         northArrow = self.myComposition.getComposerItemById('NorthArrow')
  1054.  
  1055.         # Set Data In Template
  1056.         # Set Table Content
  1057.         revisionLayer = self.getLayerByTagName("revision")
  1058.         revisionTable.setVectorLayer(revisionLayer)
  1059.  
  1060.         # Set Logos
  1061.         companyLogo.setPictureFile(self.plugin_dir + '/Logos/CompanyLogo.png')
  1062.  
  1063.         # Set Legend
  1064.         legend.setPictureFile(self.plugin_dir + '/Logos/Legende.jpg')
  1065.  
  1066.         # Set Impressum
  1067.         impressumTextFile = open(self.plugin_dir + '/Sonstiges/Anschrift.txt', 'r')
  1068.         impressumText = impressumTextFile.read()
  1069.         impressumTextFile.close()
  1070.         impressum.setText(unicode(impressumText, "utf-8" ))
  1071.  
  1072.         # Set Frames
  1073.         frameData = self.getRimoComposerData(self.tenantId, self.clusterOop)
  1074.         regionFrameText.setText(frameData["cluster"] )
  1075.         parentFrameText.setText(frameData["region"])
  1076.         bauabschnittFrameText.setText(frameData["siteCluster"])
  1077.  
  1078.         # Set Main Map
  1079.         mainMap.setNewScale(int(cScale), True)
  1080.         mainMapLayerSet = [
  1081.             self.getLayerByTagName("Direction Lines").id(),
  1082.             self.getLayerByTagName("Buildings").id(),
  1083.             self.getLayerByTagName("FCPs").id(),
  1084.             self.getLayerByTagName("Access Nodes").id(),
  1085.             self.getLayerByTagName("Trenches").id(),
  1086.             self.getLayerByTagName("Route Locations").id(),
  1087.             self.getLayerByTagName("DKM").id(),
  1088.             self.getLayerByTagName("Geoland Basemap Grau").id(),
  1089.             atlasGrid.id()
  1090.         ]
  1091.         mainMap.setLayerSet(mainMapLayerSet)
  1092.         mainMap.setKeepLayerSet(True)
  1093.         mainMap.setUpdatesEnabled(True)
  1094.  
  1095.         # Set NorthArrow
  1096.         northArrow.setPictureFile(self.plugin_dir + '/Logos/NorthArrow_04.svg')
  1097.  
  1098.         # Set Overview Map
  1099.         overviewMap.zoomToExtent(transform.transformBoundingBox(atlasGrid.extent()))
  1100.         overviewMapLayerSet = [
  1101.             self.getLayerByTagName("Trenches").id(),
  1102.             atlasGrid.id()
  1103.         ]
  1104.         overviewMap.setLayerSet(overviewMapLayerSet)
  1105.         overviewMap.setKeepLayerSet(True)
  1106.         overviewMap.setUpdatesEnabled(False)
  1107.  
  1108.  
  1109.         if (createAtlas == "Atlas") or (createAtlas == "Atlas_StaticLegend"):
  1110.             # Create Atlas
  1111.             myAtlas = self.myComposition.atlasComposition()
  1112.             myAtlas.setEnabled(True)
  1113.  
  1114.             # Set OverviewMap in Overview
  1115.             overviewMap.overview().setFrameMap(0)
  1116.  
  1117.             # Atlas Settings
  1118.             myAtlas.setCoverageLayer(atlasGrid)
  1119.             myAtlas.beginRender()
  1120.             myAtlas.setFeatureFilter('"data_in_g"  = 1')
  1121.             myAtlas.setFilterFeatures(True)
  1122.             myAtlas.setPageNameExpression('Page')
  1123.             myAtlas.setSortKeyAttributeName('ID')
  1124.             myAtlas.setSortFeatures(True)
  1125.             myAtlas.setEnabled(False)
  1126.             myAtlas.setEnabled(True)
  1127.             myAtlas.setFilenamePattern("'" + self.regionName + "_" + self.clusterName + "_" + self.siteClusterName + "_'||\"Page\"")
  1128.             mainMap.setAtlasDriven(True)
  1129.             self.myComposition.setAtlasMode(QgsComposition.PreviewAtlas)
  1130.             mainMap.setNewScale(int(cScale), True)
  1131.             self.myComposition.setAtlasMode(QgsComposition.ExportAtlas)
  1132.  
  1133.         if createAtlas != "Atlas":
  1134.             # Set OverviewMap in Overview
  1135.             overviewMap.overview().setFrameMap(0)
  1136.             currentExtent = self.iface.mapCanvas().extent()
  1137.             mainMap.zoomToExtent(currentExtent)
  1138.             mainMap.setNewScale(int(cScale), True)
  1139.  
  1140.         # Create Watermark if Development
  1141.         if self.isDev():
  1142.             watermark = QgsComposerLabel(self.myComposition)
  1143.             watermark.setText("Attention - Development")
  1144.             watermark.setItemPosition(20, 20)
  1145.             fontsize = self.myComposition.paperHeight() / 6
  1146.             watermark.setFont(QFont("Cambria", fontsize , QFont.Bold))
  1147.             watermark.adjustSizeToText()
  1148.             self.myComposition.addComposerLabel(watermark)
  1149.  
  1150.         # Refresh Items
  1151.         self.myComposition.refreshItems()
  1152.  
  1153.  
  1154.  
  1155.  
  1156. ########################
  1157. # Print Composer Methods
  1158. ########################
  1159.  
  1160.     # Create Composer
  1161.     def createPrintComposer(self):
  1162.         global project
  1163.  
  1164.         if self.checkIfThereIsRimoData == False:
  1165.             self.renderWarning("Please load RiMo-Data at least once into this Project!")
  1166.             return
  1167.  
  1168.         # Get Selections
  1169.         cType = self.dlg.comboBox_5.currentText()
  1170.         cFormat = self.dlg.comboBox_6.currentText()
  1171.         cScale = self.dlg.comboBox_7.currentText()
  1172.  
  1173.  
  1174.         # Access GridGroup
  1175.         if self.getGridGroup() == False:
  1176.             self.renderWarning("Grid Group is missing. Can't create Composer")
  1177.             return
  1178.  
  1179.         # Create Grid Layer
  1180.         gridLayer = self.getLayerByTagName(self.gridLayerName)
  1181.         gridLayerGroup = self.getGridGroup()
  1182.         gridLayerValues = self.getGridLayerValues(cFormat, cScale)
  1183.         atlasGridName = self.createAtlasGrid(gridLayer, gridLayerGroup, gridLayerValues)
  1184.         atlasGrid = self.getLayerByTagName(atlasGridName)
  1185.  
  1186.         if cType == "Individual Print":
  1187.             self.createNewRimoComposer(cScale, cFormat, atlasGrid, "Individual")
  1188.             self.saveCurrentProject()
  1189.         elif cType == "Atlas":
  1190.             self.createNewRimoComposer(cScale, cFormat, atlasGrid, "Atlas")
  1191.             self.saveCurrentProject()
  1192.         elif cType == "Atlas_StaticLegend":
  1193.             self.createNewRimoComposer(cScale, cFormat, atlasGrid, "Atlas_StaticLegend")
  1194.             self.saveCurrentProject()
  1195.         else:
  1196.             self.renderWarning("Not supported at the moment!")
  1197.  
  1198.  
  1199.  
  1200. ########################
  1201. # Overall Helper Methods
  1202. ########################
  1203.  
  1204.     # CRS Transformation
  1205.     def crsTransformation(self, inputCRS, outputCRS):
  1206.         source_crs = QgsCoordinateReferenceSystem(inputCRS)
  1207.         dest_crs = QgsCoordinateReferenceSystem(outputCRS)
  1208.         transform = QgsCoordinateTransform(source_crs, dest_crs)
  1209.         return transform
  1210.  
  1211.     # Render Warning (message as input)
  1212.     def renderWarning(self, message):
  1213.         self.iface.messageBar().clearWidgets()
  1214.         self.iface.messageBar().pushMessage(message, "", level=QgsMessageBar.WARNING)
  1215.  
  1216.  
  1217.     # Check If Dev
  1218.     def isDev(self):
  1219.         if self.rimoUrl == "https://rimo-dev.rimo-saas.com/":
  1220.             return True
  1221.         else:
  1222.             return False
  1223.  
  1224.     # Check if Project has Layer
  1225.     def checkIfProjectHasDataLayer(self):
  1226.         layers = self.iface.legendInterface().layers()
  1227.         count = 0
  1228.         for layer in layers:
  1229.             count = count + 1
  1230.         if count == 0:
  1231.             return False
  1232.         else:
  1233.             return True
  1234.  
  1235.     # Check if Project has Print Composers
  1236.     def checkIfProjectHasPrintComposer(self):
  1237.         if len(self.iface.activeComposers()) == 0:
  1238.             return False
  1239.         else:
  1240.             return True
  1241.  
  1242.     # Save Current Project
  1243.     def saveCurrentProject(self):
  1244.         global project
  1245.         p = project
  1246.         if self.isDev():
  1247.             filePath = self.dataDirectory + "/Development_" + unicode(self.tenantId) + "_" + unicode(self.regionName) + "_" + unicode(self.clusterName) + "_" + unicode(self.siteClusterName) + ".qgs"
  1248.         else:
  1249.             filePath = self.dataDirectory + "/" + unicode(self.tenantId) + "_" + unicode(self.regionName) + "_" + unicode(self.clusterName) + "_" + unicode(self.siteClusterName) + ".qgs"
  1250.  
  1251.         p.setFileName(filePath)
  1252.         p.write()
  1253.  
  1254.     # Check If Path / File Exists
  1255.     def checkIfPathExists(self, path):
  1256.         if os.path.exists(path):
  1257.             return True
  1258.         else:
  1259.             return False
  1260.  
  1261.     # Access Layer by Tag Name
  1262.     def getLayerByTagName(self, myLayer):
  1263.         layers = self.iface.legendInterface().layers()
  1264.         for layer in layers:
  1265.             keys = layer.keywordList()
  1266.             if len(keys) > 0:
  1267.                 layerName = json.loads(layer.keywordList())
  1268.                 if layerName["name"] == myLayer:
  1269.                     return layer
  1270.         #self.renderWarning("Error - Layer " + myLayer + " not found. Please contact support!")
  1271.         return False
  1272.  
  1273.     # Removes a Shapefile if Exists (Including all other files)
  1274.     def removeShapefileIfExists(self, gridName):
  1275.         layers = self.iface.legendInterface().layers()
  1276.         for layer in layers:
  1277.             if layer.name() == gridName:
  1278.                 layer = self.getLayerByTagName(gridName)
  1279.                 shpPath = os.path.dirname(layer.source())
  1280.                 shpId = layer.id()
  1281.                 shpName = layer.name()
  1282.  
  1283.                 QgsMapLayerRegistry.instance().removeMapLayer(shpId)
  1284.  
  1285.                 for filename in os.listdir(shpPath):
  1286.                     if filename.startswith(shpName):
  1287.                         os.remove(shpPath + "/" + filename)
  1288.                 return
  1289.  
  1290.     # Access GridGroup
  1291.     def getGridGroup(self):
  1292.         global project
  1293.         root = project.instance().layerTreeRoot()
  1294.         for child in root.children():
  1295.             for innerChild in child.children():
  1296.                 if isinstance(innerChild, QgsLayerTreeGroup) and innerChild.name() == "Grids":
  1297.                     return innerChild
  1298.         return False
  1299.  
  1300.     # Access BackboneGroup
  1301.     def getBackboneGroup(self):
  1302.         global project
  1303.         root = project.instance().layerTreeRoot()
  1304.         for child in root.children():
  1305.             if child.name() == "Backbone Data":
  1306.                 return child
  1307.         return False
  1308.  
  1309.     # Count Children in Group
  1310.     def getAmountOfChildrenInGroup(self, treeRoot):
  1311.         count = 0
  1312.         for child in treeRoot.children():
  1313.             count += 1
  1314.  
  1315.         return count
  1316.  
  1317.     # Set global Variables
  1318.     def setGlobalVariables(self):
  1319.         # Set Global Variables (For tasks without Login)
  1320.         if project.readEntry("rP", "tenantOop", "nothing")[0] != "nothing":
  1321.             self.rimoUrl = project.readEntry("rP", "rimoUrl", "nothing")[0]
  1322.             self.tenantOop = project.readEntry("rP", "tenantOop", "nothing")[0]
  1323.             self.tenantId = project.readEntry("rP", "tenantId", "nothing")[0]
  1324.             self.userOop = project.readEntry("rP", "userOop", "nothing")[0]
  1325.             self.dataDirectory = project.readEntry("rP", "dataDirectory", 'nothing')[0]
  1326.             self.folderPathURLEncoded = project.readEntry("rP", "folderPathURLEncoded", "nothing")[0]
  1327.             self.clusterOop = project.readEntry("rP", "clusterOop", "0")[0]
  1328.             self.regionName = project.readEntry("rP", "regionName", "nothing")[0]
  1329.             self.clusterName = project.readEntry("rP", "clusterName", "nothing")[0]
  1330.             self.siteClusterName = project.readEntry("rP", "siteClusterName", "nothing")[0]
  1331.             self.gridLayerName = project.readEntry("rP", "gridLayerName", "nothing")[0]
  1332.  
  1333.         return True
  1334.  
  1335.     # Refresh All Layer
  1336.     def refreshAllRimoDataConnections(self):
  1337.         layers = self.iface.legendInterface().layers()
  1338.         for layer in layers:
  1339.             keys = layer.keywordList()
  1340.             if len(keys) > 0:
  1341.                 layerName = json.loads(layer.keywordList())
  1342.                 if layerName["type"] == "RimoLayer":
  1343.                     layer.dataProvider().forceReload()
  1344.                     layer.triggerRepaint()
  1345.  
  1346.     # Get BackboneRegionOop
  1347.     def getBackboneRegionOop(self, clusterOop):
  1348.         global project
  1349.         r = requests.post(self.rimoUrl + "api/MIT/SDMeteorQGISController", data=json.dumps({"method": "getBackboneRegion", "Oop": clusterOop}))
  1350.         data = json.loads(r.text)
  1351.         if "_error" in data:
  1352.             return False
  1353.         if "asOop" in data:
  1354.             return data["asOop"]
  1355.  
  1356.  
  1357.     # Update Style List ComboBox
  1358.     def updateStyleListComboBox(self):
  1359.         global project
  1360.         comboBox = self.dlg.comboBox_9
  1361.         #Clear ComboBox
  1362.         comboBox.clear()
  1363.         #Return List
  1364.         comboBox.addItems(os.listdir(self.plugin_dir + "/styles"))
  1365.  
  1366.     # Get layer by Project Layer Name
  1367.     def getLayerByName(self, name):
  1368.         global project
  1369.         myLegendLayers = self.iface.legendInterface().layers()
  1370.         for myLayer in myLegendLayers:
  1371.             if name == myLayer.name():
  1372.                 return myLayer
  1373.         return False
  1374.  
  1375.  
  1376.     # Read file and find String
  1377.     def readFileAndFindString(self, filePath, string):
  1378.         with open (filePath, 'rt') as in_file:
  1379.             for line in in_file:
  1380.                 if string in line:
  1381.                     return line
  1382.  
  1383.  
  1384.     # Get Number from String
  1385.     def get_num(self, x):
  1386.         return float(re.findall("\d+\.\d+", x)[0])
  1387.  
  1388.     # Load Config Yaml
  1389.     def loadConfigYaml(self, path):
  1390.         with open(path, 'r') as stream:
  1391.             try:
  1392.                 return yaml.load(stream)
  1393.             except yaml.YAMLError as exc:
  1394.                 self.renderWarning("Config file corrupt")
  1395.                 return False
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement