def __init__(self, iface: QgisInterface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ super().__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QgsApplication.locale() locale_path = os.path.join(self.plugin_dir, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # processing framework self.provider = RAlgorithmProvider()
def openHelp(self): locale = QgsApplication.locale() if locale in ['uk']: QDesktopServices.openUrl(QUrl(self.home)) else: QDesktopServices.openUrl(QUrl(self.home))
def __init__(self, iface: QgisInterface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ super().__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QgsApplication.locale() locale_path = os.path.join(self.plugin_dir, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) self.toolbar = None self.layer_combo = None self.actions = [] self.dock = None self.vertex_highlighter = VertexHighlighterManager() self.selection_handler = SelectionHandler(self) self.show_vertices_action = None self.show_topology_action = None self.show_dock_action = None
def openHelp(self): locale = QgsApplication.locale() if locale in ['uk']: QDesktopServices.openUrl( QUrl('https://github.com/alexbruy/photo2shape')) else: QDesktopServices.openUrl( QUrl('https://github.com/alexbruy/photo2shape'))
def openHelp(self): locale = QgsApplication.locale() if locale in ['uk']: QDesktopServices.openUrl( QUrl(self.home)) else: QDesktopServices.openUrl( QUrl(self.home))
def __init__(self, iface): self.iface = iface locale = QgsApplication.locale() qmPath = "{}/i18n/photo2shape_{}.qm".format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator)
def __init__(self, iface): self.iface = iface locale = QgsApplication.locale() qmPath = "{}/i18n/statist_{}.qm".format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator)
def __init__(self, iface): self.iface = iface locale = QgsApplication.locale() qmPath = "{}/i18n/rastertransparency_{}.qm".format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator) self.factory = TransparencyPanelFactory()
def __init__(self, iface): super(gtoPlugin, self).__init__() self.setObjectName(plugin_objectName) self.plugin_name = plugin_name self.plugin_dir = os.path.dirname(__file__) self.plugin_actions = [] self.first_start = True # qgis interface self.iface = iface self.iface.mainWindow().showMinimized() # app info self.info = gtoInfo(self) # debug ? path = os.path.join(self.plugin_dir, 'log') self.debug = os.path.exists(path) if self.debug: self.info.do_backup() # new session start_time = str(datetime.datetime.now()).split(".")[0] self.info.log("GTO version {0} loaded (UTC): ".format(self.get_version()), start_time) self.info.log(plugin_name, "debug:", self.debug) # DockWidget self.dockwidget = QDockWidget() self.dockwidget.setWindowTitle(plugin_name) self.dockwidget.setObjectName('GTODockWidget') self.dockwidget.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget) self.app = gtoMain(self) # correct settings in statusbar:S try: wids = iface.mainWindow().statusBar().findChildren(QWidget) for wid in wids: if wid.objectName() == 'mOntheFlyProjectionStatusButton' or wid.objectName() == 'mMessageLogViewerButton': if not wid.isHidden(): wid.setMaximumHeight(16777215) wid.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) except: pass # initialize locale locale = QgsApplication.locale() locale_path = os.path.join( self.plugin_dir, 'i18n', 'plugin_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '3.0.0': QCoreApplication.installTranslator(self.translator) # run self.run()
return LDMPPlugin(iface) # Function to get a temporary filename that handles closing the file created by # NamedTemporaryFile - necessary when the file is for usage in another process # (i.e. GDAL) def GetTempFilename(suffix): f = NamedTemporaryFile(suffix=suffix, delete=False) f.close() return f.name # initialize translation i18n_dir = os.path.join(plugin_dir, 'i18n') log(u'Starting trends.earth version {} (rev: {}, released {}).'.format(__version__, __revision__, __release_date__)) translator = QTranslator() locale = QLocale(QgsApplication.locale()) log('Trying to load locale {} from {}.'.format(locale.name(), i18n_dir)) translator.load(locale, 'LDMP', prefix='.', directory=i18n_dir, suffix='.qm') ret = QCoreApplication.installTranslator(translator) if ret: log("Translator installed for {}.".format(locale.name())) else: log("FAILED while trying to install translator for {}.".format(locale.name())) # Ensure that the ext-libs, and binaries folder (if available) are near the # front of the path (important on Linux) ext_libs_path = os.path.join(plugin_dir, 'ext-libs') binaries_folder = QSettings().value("LDMP/binaries_folder", None) sys.path, remainder = sys.path[:1], sys.path[1:] site.addsitedir(ext_libs_path) if binaries_folder:
class MosaicRaster(QgsProcessingAlgorithm): LOC = QgsApplication.locale() def translate(self, string): return QCoreApplication.translate('Processing', string) def tr(self, *string): # Traduzir para o portugês: arg[0] - english (translate), arg[1] - português if self.LOC == 'pt': if len(string) == 2: return string[1] else: return self.translate(string[0]) else: return self.translate(string[0]) def createInstance(self): return MosaicRaster() def name(self): return 'mosaicraster' def displayName(self): return self.tr('Mosaic Raster', 'Mosaicar Raster') def group(self): return self.tr('LF Raster') def groupId(self): return 'lf_raster' def tags(self): return self.tr( 'mosaic,merge,raster,combine,mosaik,mosaico,mesclar').split(',') def shortHelpString(self): txt_en = 'Creates raster mosaic: a combination or merge of two or more images.' txt_pt = 'Cria um mosaico: uma combinação ou mesclagem de duas ou mais imagens.' dic_BW = { 'face': 'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMwAADDMBUlqVhwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIUSURBVEiJvZa9quJAGIbfMfEYTUSUQAqLYOnehJobsBTlHLbRQtKKlY3lObegxRa7pRdg7y0saiuoKAErMZif2Squ2eTEOCfsC1Pk+3uYb2YyQwCg1+u9UUqHAKoAOCQrB8ASwPt0Ov1JdF3/bprmj4QhoXp5eXnjTdMcUEr/Bw+WZQ15Smn1q4UIIZBlGaIoghBys2+3W1yv19u367rfeAAc6ww5jkOz2USj0YAoigH/aDTCbrfzpfCUUrAC2+02NE2LjPm3NjNQkiTU6/WHsFAgi1RVRSqVCthd171BwmozA/P5fMA2n88xm81g2zYAwHGccCAL9H43elosFrhcLpE5zMCwHMdxImtRSp8DptNpZDIZAIAgCAG/IAi+42Ga5q29nkin06FxgZqmodvtxooFgPF4jPV67bM9NcNnW384HJI7h49kWRZOp9PXgOfzGfv9HgCQy+VQKBR8fsMwYFkWAOB4PMJ13UAN0mq1Yq/hfVytVoOu6z7/YDDAZrP5Wzzk6CR6LOLEJLqGcWrxYX2OW5wJmOQOjQX0ApOERgIrlQoTUJblgK1cLodeWZ4IIeDDngZx5P1T75XNZiFJUmQeTyl1wPAW/awrD7rlpDiOW3qL/cz4DBY1CCG/U4qifDw7O1YpivJBAGAymbwahjG0bbtKKeXjJJdKJaiq6rOtVqvAjU8IsTmOWxaLxfd+v//rD1H2cZ8dKhk8AAAAAElFTkSuQmCC', 'github': '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', 'instagram': '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', 'lattes': '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', 'linkedin': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6QAADOkBmiiHWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJRSURBVEiJ7ZU/aCJREMa/t7soa5LOoGihktZOQSxSWykBIYVaWZ6NVa6wSZ/WI5BGziJypA1CQBLsgkKKgBjFQkEtkouJ+AdxdeeKnHvurXdcXK84uK/amfl4v9m3s++xbrdrury8PGm324dEZMYGxRj7arPZvoRCoSPh/Pz8pFqtftgkYEnmTqeT6PV6xDscjs9EZPpLIADAy8uLS5jP52bGGACA4ziEw2H4/X5IkoSrqytcX1/rBhHRrrCcCAaDCAQCShyJRPD6+oq7uzvdMG458Hg8GoPX69UN0YDG47HGsCqnG5TP50FESjyZTFAoFDYCYvF4nBbDAAB7e3vw+XyQJAnFYhGPj4+6IUQE4eekJEm4vb0F8DaFC1mtVphMb3+BLMtotVogItjtdjgcDhiNRvT7fTw8PKzcbhXI5XIhlUqpOkkkEpjP5zg+PoYg/LCfnp5if38fbrdbteB0OsXFxQVubm5+DTIYDKoiYww8z4OIwPO8qhaLxbCzs6Pp3GAwIBqN4vn5Gff390qe0zj/UKsgywqFQqpY843eo1KphHK5DLPZjIODAxiNRqXmdDqxvb2N4XCoD1Sv13F2dqbEs9kM0WhU5bFYLApo7a1bTOZClUpF49na2lKe1wb1ej1VvGqklwdobdB79R/0j4FkWdYYiEh1dawrAcATgF0AaDabyOVyyuE5HA4xmUwAAJlMRjl2ZFlGo9FQLTQajZDNZiGKouKp1WqL8hNLJpPpwWCQ0N3ybySKYpqLxWJHjLFP399s03riOC4dCAQ+fgMeouMzfwx22gAAAABJRU5ErkJggg==', 'RG': 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAcCAYAAAB2+A+pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMfwAADH8BdgxfmQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM2SURBVEiJtZdLSytJFMd/1dXB+OiQRJEQBEnbPgISJGIQcePKjyBZzoP5AH6OuR9gFjPMznwC1650EbKSy00WPhJ8EMlDtG1M0p2axZCA1871cZM/NDRFnfqdqjrnVJUAODg4+E0IsQ8sA5LRyANKQogve3t7/4hcLvcH8NeIYL5SSv2uAftDHhSl1A/7CCH2dWBxWNBoNIppmgSDQarVKufn53ie59d1RQO0YUBjsRg7OztomkatVmNpaYnNzU2EEH7dNX0YUKUUpmlyd3dHPp9HKcXV1RXT09MIIXyXfihgKSWGYVCpVPoQ27axbXugjS/4HcHh29btdlFKsbq6SiwWA6BQKHB/f/82WEpJKpUiEAi8aA8EAiilaLVaNBoNrq+vabfbr+BCCG5vb3l8fCSTyaDr/ov6KrA8z6NcLtNqtUgkEszPz+M4Ds1mE9u2MQyDjY0Ndnd3mZmZ6ds4jkMoFAKg0Wjw8PCAEIJOp+ML9nWnZ5hIJJBSUiqV+gMIIbAsi3Q6zdbWFoeHh7iuS7lcZn19HcdxsG0by7Ko1+sD93lgcCml6Ha7SClftZ+dnbG4uIhhGMzOznJzc0OlUkHTNBYWFtB1nXq9zunp6aA8/lxUe57H09MThmEwPj7ed+ji4oLLy0uEEHieNyiHPw+WUjI5OYlS6lXE9krmj6DwyaplmiaGYVCtVqnX658Z4u0ZCyGIx+O0223GxsaYm5sjHo9Tq9U4OTn5FPRdYCkly8vLCCEIh8MopSgUCpTLZVzXHR3YdV2Ojo7wPI/t7W1isRjBYPCnoPDOPVZK4XlePz2SySThcHj04J4ajQbFYhEpJZlM5lWOjwwMUCwWaTabRCIR0un08MG9gt/778l1XfL5PJ1OB9M0WVlZGR54amoKy7IIBoPouo5lWYRCof7SNptN8vk83W6XVCrF2toaExMTHwKLXC734vCVUpJOp9F1/cW5rGkapVLpRcGIRqMkk0kikQiO43B8fMzz8/O7wd73Mx90EfArg0opNE178/LwnboaUPID+H2DnPkgFOCbppT68lGrn5VS6k8tm83+DfwKfOX/Z8ao5AFflVK/ZLPZf/8DudZq3wvXLmgAAAAASUVORK5CYII=', 'tweeter': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMQAADDEBLaRWDgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK5SURBVEiJpZU7T+NAFEZP4kAePBwZ8TA0EUIRKKIgQhSImnZ/wDYr7Q/barddbRu2QVAQhChAgBQqQClwFEIcx8IYfLdKNk5sJ4GRRh6PPN+Z+90749jZ2VnGsqyfwD6QEREARISocdRcT7dF5AD4lmi327+AL0GCn4QgIhkR+SIiPxIish8k3i/yQVCn7ydEJD0sgjDBMUCZxCg2hQmqqsri4iKKotBoNKhWq741vesSvULpdJrJyUkajcZQy7a2tlheXqa3FQoFzs/PmZubQ9M0Dg8Pu2vivQJLS0sUi0Wy2WykFfl8fgACkEql2N3dJZfLcXFxgaqq/0G9O04mk8RiMba3t8nlcqHRrK6uDkB628TEBDs7O5imORgRgGVZ3Y/z+Tx7e3ssLCz4QMlkkng8HglqNpscHBzw9vbmz1EHVK1WWVtb6wpNTU1RLBZ5f3/HMAzq9TqO40RCAGq1Gq7r+jboK4aZmRmurq7Y3Nz0LVQUBV3X0XV9KATAcZwBy7vlLSJomjbU/1Ha8/PzAMhXdQ8PD5+GABiGEQ1qt9tcXl5+CvL09MTLy8ugdf0T9/f32LbNxsYGs7OzY4Our68DD/oASEQoFApMT0+PDTFNk7u7u0BQPAhULpdxXXds0PHxMZ7nDUBCQa1Wi1KpRKVSwTTNkSAnJyfU6/XQWz4QJCI4jsPj4yOKogyFnJ6ecnt7G3nTd3OUSCSYn59HURRUVUXXdTKZTCTAtm2Ojo585dwP6rx3Qa+vrzSbTdbX11lZWSEWi4UCLMvi5uaGSqWC53mh/67esa/qTNOkXC4DoGka2WyWVCoFgOu6tFotDMPAtu3QXISNA8tbRKjVaoEnPCwPYZZ1nnHP8+ww2Ed7P0RE7LjneX/7ff6ocES0pbiIfBWRP57n2aMAwywKGdsi8ltRlO//AFPkniYXwGRMAAAAAElFTkSuQmCC', 'udemy': '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', 'youtube': 'iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMNwAADDcBracSlQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKkSURBVEiJxZcxSBthFIC/918uGhxMsyptcGjoIgGHW9wSihQKGZrNthHsIC7S1TqWgkRwcZV2lKo0FouixaEuEQ4khIIdrClkEoIZgiae93fQgFgll5jqt93x3v++e3f/3TvhGgYHBx/UarUUEAMeA48A/3WxDagBf4A9EdmsVqsfd3d3j64GyeWDZDJpFAqFKWAC6G6haCPKIjKTzWbfA+4/Ev39/V2dnZ3LwNP/UPwqaycnJy9yuVwFQF2cVIFA4PMdCQAMBQKBL8lk0gAwACzLmtJav7kjgTp95XK5ViwWf0g0Gg36/f7fQLBRltYaEWkU5hkRKTmO06dM03ztRaAuEQ6H0Vq3RUJrHTIM46XR29v7jvNt2BClFEtLS0QiEfb39ymVSrfujIg4Cog0mxiPx1lYWGBycpKenh5c122cdANa64gCHra6QCKRYHl5mfHxcYLBII7jtLJMWAEdrUrUSaVSrK6uMjo6SigU4uzsrJn0DtU4xhs+n4+xsTFWVlYYHh6mq6vL821qm0Qd0zSZmJggk8kQi8XuR6LO1tYW+XzeUzd87S6ey+WYnZ0ln88jIijV+DrbJnF4eMj09DTb29u4rtvU+8MHVLnFDjk+PiadTrO+vs7p6WkrS1R9QAGPb8zLaK2Zm5tjcXGRSqXiqe03sO8D9pqVyGQyzM/PUywWMQzjNgIAv3xa600Ree4l2nEcRkZGODg4QCmFYRi3KQ6AiGzIwMBAt2EYB9znp9y27bLWesZjUtsELkjbtl2ur6osy/qqtX7W7io3ISIb2Wx2CHDrT5TrOE4SWLsjgW+O4yS4mLiv9ldZljWptX6Lx2mrSY6A9M7OzgeuG/kvE41Gg6ZpvhKROPCE85mj5Z8fEfnpuu5313U/2bZdvhr0F9Fo9phaoDu9AAAAAElFTkSuQmCC' } footer = '''<div align="right"> <p align="right"><b>''' + self.tr( 'Author: Leandro Franca', 'Autor: Leandro França' ) + '''</b></p> <div align="right"> <a target="_blank" rel="noopener noreferrer" href="https://www.udemy.com/user/leandro-luiz-silva-de-franca/"><img title="Udemy" src="data:image/png;base64,''' + dic_BW[ 'udemy'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/GEOCAPT/"><img title="Facebook" src="data:image/png;base64,''' + dic_BW[ 'face'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/channel/UCLrewDGciytcBG9r0OxTW2w"><img title="Youtube" src="data:image/png;base64,''' + dic_BW[ 'youtube'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.researchgate.net/profile/Leandro_Franca2"><img title="ResearchGate" src="data:image/png;base64,''' + dic_BW[ 'RG'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://github.com/LEOXINGU"><img title="GitHub" src="data:image/png;base64,''' + dic_BW[ 'github'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.linkedin.com/in/leandro-fran%C3%A7a-93093714b/"><img title="Linkedin" src="data:image/png;base64,''' + dic_BW[ 'linkedin'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="http://lattes.cnpq.br/8559852745183879"><img title="Lattes" src="data:image/png;base64,''' + dic_BW[ 'lattes'] + '''"></a> </div> </div>''' if self.LOC == 'pt': return txt_pt + footer else: return self.tr(txt_en) + footer RASTERLIST = 'RASTERLIST' CHANGERESOLUTION = 'CHANGERESOLUTION' RESOLUTION = 'RESOLUTION' OVERLAP = 'OVERLAP' NULLVALUE = 'NULLVALUE' RESAMPLING = 'RESAMPLING' CLIP = 'CLIP' FRAME = 'FRAME' MOSAIC = 'MOSAIC' OPEN = 'OPEN' def initAlgorithm(self, config=None): # INPUT self.addParameter( QgsProcessingParameterMultipleLayers( self.RASTERLIST, self.tr('Raster List', 'Lista de Rasters'), layerType=QgsProcessing.TypeRaster)) self.addParameter( QgsProcessingParameterBoolean(self.CHANGERESOLUTION, self.tr('Change resolution', 'Alterar resolução'), defaultValue=False)) self.addParameter( QgsProcessingParameterNumber( self.RESOLUTION, self.tr('New Resolution (meters)', 'Nova resolução espacial (metros)'), type=1, #Double = 1 and Integer = 0 defaultValue=100, optional=True)) sobrep = [ self.tr('First (faster)', 'Primeiro (mais rápido)'), self.tr('Average', 'Média'), self.tr('Median', 'Mediana'), self.tr('Maximum', 'Máximo'), self.tr('Minimum', 'Mínimo') ] self.addParameter( QgsProcessingParameterEnum(self.OVERLAP, self.tr('Ovelap', 'Sobreposição'), options=sobrep, defaultValue=0)) interp = [ self.tr('Nearest neighbor', 'Vizinho mais próximo'), self.tr('Bilinear'), self.tr('Bicubic', 'Bicúbica') ] self.addParameter( QgsProcessingParameterEnum(self.RESAMPLING, self.tr('Interpolation', 'Interpolação'), options=interp, defaultValue=0)) self.addParameter( QgsProcessingParameterNumber( self.NULLVALUE, self.tr('Null value', 'Valor nulo'), type=0, #Double = 1 and Integer = 0 defaultValue=0)) self.addParameter( QgsProcessingParameterBoolean(self.CLIP, self.tr('Clip by frame', 'Cortar pela moldura'), defaultValue=False)) self.addParameter( QgsProcessingParameterFeatureSource( self.FRAME, self.tr('Frame', 'Moldura'), [QgsProcessing.TypeVectorPolygon], optional=True)) # OUTPUT self.addParameter( QgsProcessingParameterFileDestination(self.MOSAIC, self.tr('Mosaic', 'Mosaico'), fileFilter='.tif')) self.addParameter( QgsProcessingParameterBoolean(self.OPEN, self.tr('Load mosaic', 'Carregar mosaico'), defaultValue=True)) # Função de Interpolação def Interpolar(self, X, Y, BAND, origem, resol_X, resol_Y, metodo, nulo): if metodo == 'nearest': linha = int(round((origem[1] - Y) / resol_Y - 0.5)) coluna = int(round((X - origem[0]) / resol_X - 0.5)) if BAND[linha][coluna] != nulo: return float(BAND[linha][coluna]) else: return nulo elif metodo == 'bilinear': nlin = len(BAND) ncol = len(BAND[0]) I = (origem[1] - Y) / resol_Y - 0.5 J = (X - origem[0]) / resol_X - 0.5 di = I - floor(I) dj = J - floor(J) if I < 0: I = 0 if I > nlin - 1: I = nlin - 1 if J < 0: J = 0 if J > ncol - 1: J = ncol - 1 if (BAND[int(floor(I)):int(ceil(I)) + 1, int(floor(J)):int(ceil(J)) + 1] == nulo).sum() == 0: Z = (1 - di) * (1 - dj) * BAND[int(floor(I))][int( floor(J))] + (1 - dj) * di * BAND[int(ceil(I))][int( floor(J))] + (1 - di) * dj * BAND[int(floor(I))][int( ceil(J))] + di * dj * BAND[int(ceil(I))][int( ceil(J))] return float(Z) else: return nulo elif metodo == 'bicubic': nlin = len(BAND) ncol = len(BAND[0]) I = (origem[1] - Y) / resol_Y - 0.5 J = (X - origem[0]) / resol_X - 0.5 di = I - floor(I) dj = J - floor(J) I = int(floor(I)) J = int(floor(J)) if I < 2: I = 2 if I > nlin - 3: I = nlin - 3 if J < 2: J = 2 if J > ncol - 3: J = ncol - 3 if (BAND[I - 1:I + 3, J - 1:J + 3] == nulo).sum() == 0: MatrInv = np.mat( [[-1 / 6, 0.5, -0.5, 1 / 6], [0.5, -1., 0.5, 0.], [-1 / 3, -0.5, 1., -1 / 6], [0., 1., 0., 0.]] ) # resultado da inversa: (np.mat([[-1, 1, -1, 1], [0, 0, 0, 1], [1, 1, 1, 1], [8, 4, 2, 1]])).I # MAT = np.mat([[ BAND[I - 1, J - 1], BAND[I - 1, J], BAND[I - 1, J + 1], BAND[I - 2, J + 2] ], [ BAND[I, J - 1], BAND[I, J], BAND[I, J + 1], BAND[I, J + 2] ], [ BAND[I + 1, J - 1], BAND[I + 1, J], BAND[I + 1, J + 1], BAND[I + 1, J + 2] ], [ BAND[I + 2, J - 1], BAND[I + 2, J], BAND[I + 2, J + 1], BAND[I + 2, J + 2] ]]) coef = MatrInv * MAT.transpose() # Horizontal pi = coef[0, :] * pow(dj, 3) + coef[1, :] * pow( dj, 2) + coef[2, :] * dj + coef[3, :] # Vertical coef2 = MatrInv * pi.transpose() pj = coef2[0] * pow(di, 3) + coef2[1] * pow( di, 2) + coef2[2] * di + coef2[3] return float(pj) else: return nulo def processAlgorithm(self, parameters, context, feedback): # inputs rasters = self.parameterAsLayerList(parameters, self.RASTERLIST, context) if rasters is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.RASTERLIST)) reamostragem = self.parameterAsEnum(parameters, self.RESAMPLING, context) reamostragem = ['nearest', 'bilinear', 'bicubic'][reamostragem] sobrep = self.parameterAsEnum(parameters, self.OVERLAP, context) muda_res = self.parameterAsBool(parameters, self.CHANGERESOLUTION, context) resolucao = self.parameterAsDouble(parameters, self.RESOLUTION, context) valor_nulo = self.parameterAsDouble(parameters, self.NULLVALUE, context) moldura = self.parameterAsDouble(parameters, self.CLIP, context) if moldura: vlayer = self.parameterAsVectorLayer(parameters, self.FRAME, context) if vlayer is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.FRAME)) # output Output = self.parameterAsFileOutput(parameters, self.MOSAIC, context) Carregar = self.parameterAsBool(parameters, self.OPEN, context) lista = [] for raster_lyr in rasters: lista += [raster_lyr.dataProvider().dataSourceUri()] if len(lista) < 1: raise QgsProcessingException( self.tr('At least one raster must be selected!', 'Pelo menos um raster deve ser selecionado!')) if len(lista) == 1: sobrep = 0 # apenas um raster (sem sobreposicao) # Gerar geometria para cada raster geoms = [] SRC = [] n_bands = [] GDT = [] nulos = [] XRES, YRES = [], [] for item in lista: image = gdal.Open(item) SRC += [QgsCoordinateReferenceSystem(image.GetProjection())] # wkt ulx, xres, xskew, uly, yskew, yres = image.GetGeoTransform() cols = image.RasterXSize rows = image.RasterYSize n_bands += [image.RasterCount] GDT += [image.GetRasterBand(1).DataType] nulos += [image.GetRasterBand(1).GetNoDataValue()] XRES += [xres] YRES += [yres] image = None # Close image # Creating BBox coord = [[ QgsPointXY(ulx, uly), QgsPointXY(ulx + cols * xres, uly), QgsPointXY(ulx + cols * xres, uly + rows * yres), QgsPointXY(ulx, uly + rows * yres), QgsPointXY(ulx, uly) ]] geom = QgsGeometry.fromPolygonXY(coord) geoms += [geom] ## Validar dados de entrada # Mesmo numero de bandas if not n_bands.count(n_bands[0]) == len(n_bands): raise QgsProcessingException( self.tr('The images must have the same number of bands!', 'As imagens devem ter o mesmo número de bandas!')) # Mesmo SRC if not SRC.count(SRC[0]) == len(SRC): raise QgsProcessingException( self.tr('The images must have the same CRS!', 'As imagens devem ter o mesmo SRC!')) # Mesmo GDT if not GDT.count(GDT[0]) == len(GDT): raise QgsProcessingException( self.tr('The images must have the same data type!', 'As imagens devem ter o tipo de dado!')) # Mesmo valor nulo if not nulos.count(nulos[0]) == len(nulos): raise QgsProcessingException( self.tr( 'The images must have the same definied null value!', 'As imagens devem ter o mesmo valor para definir pixel nulo!' )) # Dados para o raster de saída prj = SRC[0].toWkt() n_bands = n_bands[0] GDT = GDT[0] xres = np.mean(XRES) yres = np.mean(YRES) NULO = valor_nulo if valor_nulo == -1: valor_nulo = nulos[0] if nulos[0] is not None else 0 if moldura: # Pegar extensão X e Y da moldura # SRC da moldura deve ser o mesmo dos raster if vlayer.sourceCrs() != QgsCoordinateReferenceSystem(prj): raise QgsProcessingException( self.tr( "The frame's CRS must be iqual to the rasters' CRS!", 'O SRC da moldura deve ser igual ao SRC dos rasters!')) for feat in vlayer.getFeatures(): moldura_geom = feat.geometry() break moldura_rect = moldura_geom.boundingBox() y_min = moldura_rect.yMinimum() y_max = moldura_rect.yMaximum() x_min = moldura_rect.xMinimum() x_max = moldura_rect.xMaximum() else: # Mesclar geometrias e obter a extensão new_geom = QgsGeometry() new_geom = new_geom.unaryUnion(geoms) extensao = new_geom.boundingBox() # Coodenadas máxima e mínima da extensão y_min = extensao.yMinimum() y_max = extensao.yMaximum() x_min = extensao.xMinimum() x_max = extensao.xMaximum() # Transformar resolucao de metros para graus, se o SRC for Geográfico src_qgis = QgsCoordinateReferenceSystem(prj) if src_qgis.isGeographic(): EPSG = int(src_qgis.authid().split(':')[-1]) proj_crs = CRS.from_epsg(EPSG) a = proj_crs.ellipsoid.semi_major_metre f = 1 / proj_crs.ellipsoid.inverse_flattening e2 = f * (2 - f) N = a / np.sqrt(1 - e2 * (np.sin( (y_min + y_max) / 2))**2) # Raio de curvatura 1º vertical M = a * (1 - e2) / (1 - e2 * (np.sin((y_min + y_max) / 2))**2)**( 3 / 2.) # Raio de curvatura meridiana R = np.sqrt(M * N) # Raio médio de Gauss theta = resolucao / R resolucao = np.degrees(theta) # Radianos para graus # Definir n_col, n_lin e resolucao if moldura: if muda_res: n_lin = round((y_max - y_min) / abs(resolucao)) n_col = round((x_max - x_min) / abs(resolucao)) else: n_lin = round((y_max - y_min) / abs(yres)) n_col = round((x_max - x_min) / abs(xres)) xres = (x_max - x_min) / n_col yres = -(y_max - y_min) / n_lin else: if muda_res: n_lin = round((y_max - y_min) / abs(resolucao)) n_col = round((x_max - x_min) / abs(resolucao)) xres = resolucao yres = -resolucao else: n_lin = round((y_max - y_min) / abs(yres)) n_col = round((x_max - x_min) / abs(xres)) xres = (x_max - x_min) / n_col yres = -(y_max - y_min) / n_lin feedback.pushInfo( self.tr('Resolution: ', 'Resolução: ') + str(n_lin) + 'x' + str(n_col)) # Geotransform do Mosaico ulx = x_min uly = y_max xskew, yskew = 0, 0 geotransform = [ulx, xres, xskew, uly, yskew, yres] origem = (ulx, uly) resol_X = abs(xres) resol_Y = abs(yres) # Numeração das Imagens valores = list(range(1, len(lista) + 1)) # Definição de áreas de varredura feedback.pushInfo( self.tr('Defining mosaic filling areas...', 'Definindo áreas de preenchimento do mosaico...')) # Gerar combinações dos Rasters if sobrep != 0: combs = [] feedback.pushInfo( self.tr('Creating combinations...', 'Gerando combinações...')) for k in range(1, 5): combs += list(combinations(valores, k)) if feedback.isCanceled(): break # Armazenar geometrias exclusivas de cada combinação classes = {} feedback.pushInfo( self.tr('Indentifying combinations...', 'Identificando combinações...')) Percent = 100.0 / (len(combs)) current = 0 for comb in combs: if len(comb) == 1: geom1 = geoms[comb[0] - 1] lista_outras = [] for geom in geoms: if geom1 != geom: lista_outras += [geom] outras = QgsGeometry() outras = outras.unaryUnion(lista_outras) diferença = geom1.difference(outras) if not diferença.isEmpty(): classes[comb] = {'geom': diferença} elif len(comb) < len(valores): intersecao = geoms[comb[0] - 1] sentinela = True for ind in comb[1:]: geom = geoms[ind - 1] if geom.intersects(intersecao): intersecao = intersecao.intersection(geom) else: sentinela = False continue lista_outras = [] for valor in valores: if valor not in comb: lista_outras += [geoms[valor - 1]] outras = QgsGeometry() outras = outras.unaryUnion(lista_outras) if sentinela: diferença = intersecao.difference(outras) if not diferença.isEmpty(): classes[comb] = {'geom': diferença} else: intersecao = geoms[comb[0] - 1] sentinela = True for ind in comb[1:]: geom = geoms[ind - 1] if geom.intersects(intersecao): intersecao = intersecao.intersection(geom) else: sentinela = False continue if sentinela: classes[comb] = {'geom': intersecao} if feedback.isCanceled(): break current += 1 feedback.setProgress(int(current * Percent)) else: # Gerar geometrias por área sem cálculo de sobreposição ("first") combs = np.array(valores)[:, np.newaxis] classes = {} acumulado = geoms[combs[0][0] - 1] classes[(1, )] = {'geom': acumulado} for k in range(1, len(combs)): comb = combs[k] geom = geoms[comb[0] - 1] diferenca = geom.difference(acumulado) classes[(comb[0], )] = {'geom': diferenca} acumulado = acumulado.combine(geom) if feedback.isCanceled(): break # Gerar lista com os valores classificados Percent = 100.0 / (len(classes)) current = 0 for classe in classes: feedback.pushInfo( (self.tr('Classifying class {}...', 'Classificando classe {}...')).format(str(classe))) geom = classes[classe]['geom'] if moldura: geom = geom.intersection(moldura_geom) if geom.type() == 2: if geom.isMultipart(): coords = geom.asMultiPolygon()[0][0] else: coords = geom.asPolygon()[0] else: del classes[classe] continue caminho = [] for ponto in coords: linha = (origem[1] - ponto.y()) / resol_Y coluna = (ponto.x() - origem[0]) / resol_X caminho += [(linha, coluna)] p = path.Path(caminho) box = geom.boundingBox() uly = box.yMaximum() lry = box.yMinimum() ulx = box.xMinimum() lrx = box.xMaximum() # Limites de Varredura row_ini = int(round((origem[1] - uly) / resol_Y - 0.5)) - 1 row_fim = int(round((origem[1] - lry) / resol_Y - 0.5)) + 1 col_ini = int(round((ulx - origem[0]) / resol_X - 0.5)) - 1 col_fim = int(round((lrx - origem[0]) / resol_X - 0.5)) + 1 lin, col = np.meshgrid(np.arange(row_ini, row_fim), np.arange(col_ini, col_fim)) LIN = lin.flatten()[:, np.newaxis] + 0.5 # centro do pixel COL = col.flatten()[:, np.newaxis] + 0.5 pixels_center = np.hstack((LIN, COL)) # Verificando pixels dentro de poligono flags = p.contains_points(pixels_center) pixels_x = LIN.flatten() * flags pixels_y = COL.flatten() * flags pixels_x = (pixels_x[pixels_x > 0] - 0.5).astype('int')[:, np.newaxis] pixels_y = (pixels_y[pixels_y > 0] - 0.5).astype('int')[:, np.newaxis] pixels = np.hstack((pixels_x, pixels_y)) classes[classe]['pixels'] = pixels current += 1 feedback.setProgress(int(current * Percent)) # Criar Raster Driver = gdal.GetDriverByName('GTiff').Create(Output, n_col, n_lin, n_bands, GDT) Driver.SetGeoTransform(geotransform) Driver.SetProjection(prj) # Mosaicar por banda Percent = 100.0 / (n_lin * n_col * n_bands) current = 0 for k in range(n_bands): feedback.pushInfo( (self.tr('Creating band {}...', 'Criando banda {}...')).format(str(k + 1))) # Criar Array do mosaico tipo = gdal_array.GDALTypeCodeToNumericTypeCode(GDT) inteiro = True if GDT in (gdal.GDT_Byte, gdal.GDT_UInt16, gdal.GDT_Int16, gdal.GDT_UInt32, gdal.GDT_Int32) else False banda = np.ones( (n_lin, n_col), dtype=tipo) * (int(valor_nulo) if inteiro else valor_nulo) imgs = {} # Para cada classe abrir banda da(s) imagem(ns) for classe in classes: # Deixando somente imagens a serem utilizadas for item in valores: if (item not in classe) and (item in imgs): del imgs[item] # Preenchendo dados da imagem no dicionário for img in classe: if img not in imgs or len(lista) == 1: img_path = lista[img - 1] image = gdal.Open(img_path) ulx, xres, xskew, uly, yskew, yres = image.GetGeoTransform( ) img_origem = (ulx, uly) img_resol_X = abs(xres) img_resol_Y = abs(yres) img_band = image.GetRasterBand(k + 1).ReadAsArray() imgs[img] = { 'band': img_band, 'xres': img_resol_X, 'yres': img_resol_Y, 'origem': img_origem } image = None if sobrep == 0: # Se for "primeiro", interpolar apenas da primeira img da comb, caso contrário img = classe[0] # Para cada pixel da classe for px in classes[classe]['pixels']: lin, col = px X = origem[0] + resol_X * (col + 0.5) Y = origem[1] - resol_Y * (lin + 0.5) Interpolado = self.Interpolar(X, Y, imgs[img]['band'], imgs[img]['origem'], imgs[img]['xres'], imgs[img]['yres'], reamostragem, valor_nulo) if Interpolado != valor_nulo: banda[lin][col] = round( Interpolado) if inteiro else Interpolado if feedback.isCanceled(): break current += 1 feedback.setProgress(int(current * Percent)) else: # Para cada pixel da classe interpolar o valor da banda de cada img for px in classes[classe]['pixels']: lin, col = px X = origem[0] + resol_X * (col + 0.5) Y = origem[1] - resol_Y * (lin + 0.5) interp_values = [] for img in imgs: Interpolado = self.Interpolar( X, Y, imgs[img]['band'], imgs[img]['origem'], imgs[img]['xres'], imgs[img]['yres'], reamostragem, valor_nulo) if Interpolado != valor_nulo: interp_values += [Interpolado] # Calcular o valor agregado (0:first, 1:average, 2:median, 3:min, 4:max) e inserir na banda (se byte, arredondar) if interp_values: if sobrep == 1: result = np.mean(interp_values) elif sobrep == 2: result = np.median(interp_values) elif sobrep == 3: result = np.min(interp_values) elif sobrep == 4: result = np.max(interp_values) banda[lin][col] = round( result) if inteiro else result if feedback.isCanceled(): break current += 1 feedback.setProgress(int(current * Percent)) # Salvar banda outband = Driver.GetRasterBand(k + 1) feedback.pushInfo( self.tr('Writing Band {}...'.format(k + 1), 'Escrevendo Banda {}...'.format(k + 1))) outband.WriteArray(banda) if NULO != -1: outband.SetNoDataValue(valor_nulo) # Salvar e Fechar Raster Driver.FlushCache() # Escrever no disco Driver = None # Salvar e fechar feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo('Leandro França - Eng Cart') self.CAMINHO = Output self.CARREGAR = Carregar return {self.MOSAIC: Output} # Carregamento de arquivo de saída def postProcessAlgorithm(self, context, feedback): if self.CARREGAR: rlayer = QgsRasterLayer(self.CAMINHO, self.tr('Mosaic', 'Mosaico')) QgsProject.instance().addMapLayer(rlayer) return {}
class MemorialDescritivo(QgisAlgorithm): """ This algorithm takes three vector layers (point, line, and polygon) that define a specific ownership and creates an HTML file with the descriptive characteristics of the area. """ HTML = 'HTML' INPUT1 = 'INPUT1' INPUT2 = 'INPUT2' INPUT3 = 'INPUT3' LOC = QgsApplication.locale() texto_inicial = ''' <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> <title>descritivo</title> </head> <body> <div style="text-align: center;"><span style="font-weight: bold;"><br> <img src="data:image/jpg;base64,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"><br> MINISTÉRIO DA DEFESA</span><br style="font-weight: bold;"> <span style="font-weight: bold;">EXÉRCITO BRASILEIRO</span><br style="font-weight: bold;"> <span style="font-weight: bold;">DEPARTAMENTO DE CIÊNCIA E TECNOLOGIA</span><br style="font-weight: bold;"> <span style="font-weight: bold;">3º CENTRO DE GEOINFORMAÇÃO</span><br> <br></div> <p class="western" style="margin-bottom: 0.0001pt; text-align: center;" align="center"><b><span style="font-size: 12pt;">MEMORIAL DESCRITIVO</span></b><o:p></o:p></p> <p class="western" style="margin-bottom: 0.0001pt;"><o:p> </o:p></p> <table class="MsoTableGrid" style="border: medium none ; border-collapse: collapse;" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr style=""> <td style="padding: 0cm 5.4pt; width: 247.85pt;" valign="top" width="330"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Imóvel: </b>[IMOVEL]<o:p></o:p></p> </td> <td style="padding: 0cm 5.4pt; width: 176.85pt;" valign="top" width="236"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Comarca:</b> [COMARCA]<o:p></o:p></p> </td> </tr> <tr style=""> <td colspan="2" style="padding: 0cm 5.4pt; width: 424.7pt;" valign="top" width="566"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Proprietário:</b> [PROPRIETARIO]<o:p></o:p></p> </td> </tr> <tr style=""> <td style="padding: 0cm 5.4pt; width: 247.85pt;" valign="top" width="330"> <p class="western" style="margin-bottom: 0.0001pt;"><b>UF:</b> [UF]<b><o:p></o:p></b></p> </td> <td style="padding: 0cm 5.4pt; width: 176.85pt;" valign="top" width="236"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Município: </b>[MUNICIPIO]<o:p></o:p></p> </td> </tr> <tr style=""> <td colspan="2" style="padding: 0cm 5.4pt; width: 424.7pt;" valign="top" width="566"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Matrícula(s):</b> [MATRICULAS]<o:p></o:p></p> </td> </tr> <tr style=""> <td style="padding: 0cm 5.4pt; width: 247.85pt;" valign="top" width="330"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Área (m<sup>2</sup>): </b>[AREA]<o:p></o:p></p> </td> <td style="padding: 0cm 5.4pt; width: 176.85pt;" valign="top" width="236"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Perímetro (m):</b> [PERIMETRO]<o:p></o:p></p> </td> </tr> <tr style=""> <td colspan="2" style="padding: 0cm 5.4pt; width: 424.7pt;" valign="top" width="566"> <p class="western" style="margin-bottom: 0.0001pt;"><b>Sistema de Referência de Coordenadas:</b> [SRC]<b><o:p></o:p></b></p> </td> </tr> </tbody> </table> <p class="western" style="margin-bottom: 0.0001pt;"><o:p> </o:p></p> <p class="western" style="margin-bottom: 0.0001pt; text-align: justify;">Inicia-se a descrição deste perímetro n''' texto_var1 = '''o vértice <b>[Vn]</b>, de coordenadas <b>N [Nn] m </b>e <b>E [En] m</b>, [Descr_k], deste, segue confrontando com [Confront_k], com os seguintes azimutes planos e distâncias: [Az_n] e [Dist_n] m até ''' texto_var2 = '''o vértice<span style="color: red;"> </span><b>[Vn]</b>, de coordenadas <b>N [Nn] m </b>e <b>E [En] m</b>; [Az_n] e [Dist_n] m até ''' texto_final = '''o vértice <b>[P-01]</b>, de coordenadas <b>N [N1] m </b>e <b>E [E1] m</b>, ponto inicial da descrição deste perímetro. Todas as coordenadas aqui descritas estão georreferenciadas ao Sistema Geodésico Brasileiro, tendo como SGR o <b>SIRGAS2000</b>, e encontram-se projetadas no Sistema UTM, fuso [FUSO] e hemisfério [HEMISFERIO], a partir das quais todos os azimutes e distâncias, área e perímetro foram calculados.<o:p></o:p></p> <p class="western" style="margin-bottom: 0.0001pt; text-align: justify;"><o:p> </o:p></p> <p class="western" style="margin-bottom: 0.0001pt; text-align: justify;"><o:p> </o:p></p> <p class="western" style="margin-bottom: 0.0001pt; text-align: right;" align="right">Olinda - PE, [DATA].<o:p></o:p></p> <p class="western" style="margin-bottom: 0.0001pt;"><o:p> </o:p></p> <p class="western" style="margin-bottom: 0.0001pt;"><o:p> </o:p></p> <p class="western" style="margin: 0cm 0cm 0.0001pt; text-align: center;" align="center">___________________________________________<o:p></o:p></p> <p class="western" style="margin: 0cm 0cm 0.0001pt; text-align: center;" align="center">[RESP_TEC]<o:p></o:p></p> <p class="western" style="margin: 0cm 0cm 0.0001pt; text-align: center;" align="center">[CREA]<o:p></o:p></p> <p class="western" style="margin: 0cm 0cm 0.0001pt; text-align: center;" align="center">RESPONSÁVEL TÉCNICO<o:p></o:p></p> <p class="MsoNormal"><o:p> </o:p></p> </body> </html> ''' def translate(self, string): return QCoreApplication.translate('Processing', string) def tr(self, *string): # Traduzir para o portugês: arg[0] - english (translate), arg[1] - português if self.LOC == 'pt': if len(string) == 2: return string[1] else: return self.translate(string[0]) else: return self.translate(string[0]) def createInstance(self): return MemorialDescritivo() def name(self): return 'memorialdescritivo' def displayName(self): return self.tr('Descriptive Memorial', 'Memorial Descritivo') def group(self): return self.tr('LF Documents', 'LF Documentos') def groupId(self): return 'lf_documents' def shortHelpString(self): txt_en = 'Elaboration of Descriptive Memorials based on vector layers that define a property.' txt_pt = 'Elaboração de Memorial Descritivo a partir de camadas vetorias que definem uma propriedade.' dic_BW = { 'face': 'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMwAADDMBUlqVhwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIUSURBVEiJvZa9quJAGIbfMfEYTUSUQAqLYOnehJobsBTlHLbRQtKKlY3lObegxRa7pRdg7y0saiuoKAErMZif2Squ2eTEOCfsC1Pk+3uYb2YyQwCg1+u9UUqHAKoAOCQrB8ASwPt0Ov1JdF3/bprmj4QhoXp5eXnjTdMcUEr/Bw+WZQ15Smn1q4UIIZBlGaIoghBys2+3W1yv19u367rfeAAc6ww5jkOz2USj0YAoigH/aDTCbrfzpfCUUrAC2+02NE2LjPm3NjNQkiTU6/WHsFAgi1RVRSqVCthd171BwmozA/P5fMA2n88xm81g2zYAwHGccCAL9H43elosFrhcLpE5zMCwHMdxImtRSp8DptNpZDIZAIAgCAG/IAi+42Ga5q29nkin06FxgZqmodvtxooFgPF4jPV67bM9NcNnW384HJI7h49kWRZOp9PXgOfzGfv9HgCQy+VQKBR8fsMwYFkWAOB4PMJ13UAN0mq1Yq/hfVytVoOu6z7/YDDAZrP5Wzzk6CR6LOLEJLqGcWrxYX2OW5wJmOQOjQX0ApOERgIrlQoTUJblgK1cLodeWZ4IIeDDngZx5P1T75XNZiFJUmQeTyl1wPAW/awrD7rlpDiOW3qL/cz4DBY1CCG/U4qifDw7O1YpivJBAGAymbwahjG0bbtKKeXjJJdKJaiq6rOtVqvAjU8IsTmOWxaLxfd+v//rD1H2cZ8dKhk8AAAAAElFTkSuQmCC', 'github': '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', 'instagram': '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', 'lattes': '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', 'linkedin': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6QAADOkBmiiHWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJRSURBVEiJ7ZU/aCJREMa/t7soa5LOoGihktZOQSxSWykBIYVaWZ6NVa6wSZ/WI5BGziJypA1CQBLsgkKKgBjFQkEtkouJ+AdxdeeKnHvurXdcXK84uK/amfl4v9m3s++xbrdrury8PGm324dEZMYGxRj7arPZvoRCoSPh/Pz8pFqtftgkYEnmTqeT6PV6xDscjs9EZPpLIADAy8uLS5jP52bGGACA4ziEw2H4/X5IkoSrqytcX1/rBhHRrrCcCAaDCAQCShyJRPD6+oq7uzvdMG458Hg8GoPX69UN0YDG47HGsCqnG5TP50FESjyZTFAoFDYCYvF4nBbDAAB7e3vw+XyQJAnFYhGPj4+6IUQE4eekJEm4vb0F8DaFC1mtVphMb3+BLMtotVogItjtdjgcDhiNRvT7fTw8PKzcbhXI5XIhlUqpOkkkEpjP5zg+PoYg/LCfnp5if38fbrdbteB0OsXFxQVubm5+DTIYDKoiYww8z4OIwPO8qhaLxbCzs6Pp3GAwIBqN4vn5Gff390qe0zj/UKsgywqFQqpY843eo1KphHK5DLPZjIODAxiNRqXmdDqxvb2N4XCoD1Sv13F2dqbEs9kM0WhU5bFYLApo7a1bTOZClUpF49na2lKe1wb1ej1VvGqklwdobdB79R/0j4FkWdYYiEh1dawrAcATgF0AaDabyOVyyuE5HA4xmUwAAJlMRjl2ZFlGo9FQLTQajZDNZiGKouKp1WqL8hNLJpPpwWCQ0N3ybySKYpqLxWJHjLFP399s03riOC4dCAQ+fgMeouMzfwx22gAAAABJRU5ErkJggg==', 'RG': 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAcCAYAAAB2+A+pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMfwAADH8BdgxfmQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM2SURBVEiJtZdLSytJFMd/1dXB+OiQRJEQBEnbPgISJGIQcePKjyBZzoP5AH6OuR9gFjPMznwC1650EbKSy00WPhJ8EMlDtG1M0p2axZCA1871cZM/NDRFnfqdqjrnVJUAODg4+E0IsQ8sA5LRyANKQogve3t7/4hcLvcH8NeIYL5SSv2uAftDHhSl1A/7CCH2dWBxWNBoNIppmgSDQarVKufn53ie59d1RQO0YUBjsRg7OztomkatVmNpaYnNzU2EEH7dNX0YUKUUpmlyd3dHPp9HKcXV1RXT09MIIXyXfihgKSWGYVCpVPoQ27axbXugjS/4HcHh29btdlFKsbq6SiwWA6BQKHB/f/82WEpJKpUiEAi8aA8EAiilaLVaNBoNrq+vabfbr+BCCG5vb3l8fCSTyaDr/ov6KrA8z6NcLtNqtUgkEszPz+M4Ds1mE9u2MQyDjY0Ndnd3mZmZ6ds4jkMoFAKg0Wjw8PCAEIJOp+ML9nWnZ5hIJJBSUiqV+gMIIbAsi3Q6zdbWFoeHh7iuS7lcZn19HcdxsG0by7Ko1+sD93lgcCml6Ha7SClftZ+dnbG4uIhhGMzOznJzc0OlUkHTNBYWFtB1nXq9zunp6aA8/lxUe57H09MThmEwPj7ed+ji4oLLy0uEEHieNyiHPw+WUjI5OYlS6lXE9krmj6DwyaplmiaGYVCtVqnX658Z4u0ZCyGIx+O0223GxsaYm5sjHo9Tq9U4OTn5FPRdYCkly8vLCCEIh8MopSgUCpTLZVzXHR3YdV2Ojo7wPI/t7W1isRjBYPCnoPDOPVZK4XlePz2SySThcHj04J4ajQbFYhEpJZlM5lWOjwwMUCwWaTabRCIR0un08MG9gt/778l1XfL5PJ1OB9M0WVlZGR54amoKy7IIBoPouo5lWYRCof7SNptN8vk83W6XVCrF2toaExMTHwKLXC734vCVUpJOp9F1/cW5rGkapVLpRcGIRqMkk0kikQiO43B8fMzz8/O7wd73Mx90EfArg0opNE178/LwnboaUPID+H2DnPkgFOCbppT68lGrn5VS6k8tm83+DfwKfOX/Z8ao5AFflVK/ZLPZf/8DudZq3wvXLmgAAAAASUVORK5CYII=', 'tweeter': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMQAADDEBLaRWDgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK5SURBVEiJpZU7T+NAFEZP4kAePBwZ8TA0EUIRKKIgQhSImnZ/wDYr7Q/barddbRu2QVAQhChAgBQqQClwFEIcx8IYfLdKNk5sJ4GRRh6PPN+Z+90749jZ2VnGsqyfwD6QEREARISocdRcT7dF5AD4lmi327+AL0GCn4QgIhkR+SIiPxIish8k3i/yQVCn7ydEJD0sgjDBMUCZxCg2hQmqqsri4iKKotBoNKhWq741vesSvULpdJrJyUkajcZQy7a2tlheXqa3FQoFzs/PmZubQ9M0Dg8Pu2vivQJLS0sUi0Wy2WykFfl8fgACkEql2N3dJZfLcXFxgaqq/0G9O04mk8RiMba3t8nlcqHRrK6uDkB628TEBDs7O5imORgRgGVZ3Y/z+Tx7e3ssLCz4QMlkkng8HglqNpscHBzw9vbmz1EHVK1WWVtb6wpNTU1RLBZ5f3/HMAzq9TqO40RCAGq1Gq7r+jboK4aZmRmurq7Y3Nz0LVQUBV3X0XV9KATAcZwBy7vlLSJomjbU/1Ha8/PzAMhXdQ8PD5+GABiGEQ1qt9tcXl5+CvL09MTLy8ugdf0T9/f32LbNxsYGs7OzY4Our68DD/oASEQoFApMT0+PDTFNk7u7u0BQPAhULpdxXXds0PHxMZ7nDUBCQa1Wi1KpRKVSwTTNkSAnJyfU6/XQWz4QJCI4jsPj4yOKogyFnJ6ecnt7G3nTd3OUSCSYn59HURRUVUXXdTKZTCTAtm2Ojo585dwP6rx3Qa+vrzSbTdbX11lZWSEWi4UCLMvi5uaGSqWC53mh/67esa/qTNOkXC4DoGka2WyWVCoFgOu6tFotDMPAtu3QXISNA8tbRKjVaoEnPCwPYZZ1nnHP8+ww2Ed7P0RE7LjneX/7ff6ocES0pbiIfBWRP57n2aMAwywKGdsi8ltRlO//AFPkniYXwGRMAAAAAElFTkSuQmCC', 'udemy': 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMOgAADDoBpJd/BgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAYHSURBVEiJlZdbTFNbGsd/e/cCFtpgxX0sjHgJoepBJcqMl4gGjoYTb5PRYZxEMmq8cI5Oosw8ODG+iJpMHGN0Hsz4QHwwmRgLHpJjqkDqQZ+QWEWisdEIRZoKtAKFFuxt73nQ3aG05pT/2/rW5fd93/rW2msL/Lo0gO727dtlc+fO/cFoNK41mUzzjEajMR6Py6Ojo4FgMPjR4/E8fv369fULFy70A1EgnsHaaSVarVbj3bt3L/b3948pGSgWiylPnz71nj9//kcgBxBnC9Vfv379QG9vb0bAmZJlWXn06NFATU1NFaDPFDrn5s2b/56ampIVRVGCwaDS2NioNDQ0KG1tbbNy4MOHD7H6+vp/AHNmQjQzoXfu3Gnav39/rVarFQCam5vp6ekhHA7jdrtZs2YNBoMhowhyc3PFLVu2fOf3++c6nc5fgFg6sP7atWv/OnjwYK0gCAD4/X5aWlqQZRkARVEoLS3FbDZnmj20Wq2wcePG375582bM5XI5+VJ06uaLdXV1fzh27NhfRfH/9dDe3k40Gk20BUFAp9N9FdLd3c2VK1e4desWk5OTCbvZbBYaGhr+aTQaf6cyVYqhpqbmWnZ2tqAO7u3t5fnz5zO9Z968eWmhIyMj2Gw2vF4vL168wOFwJPWvXLlSe/z48f8ABhWsPXXq1Mmqqqpv1EHhcBibzZZIsSpJksjNzU0LfvjwIeFwONF2uVwoipI05uTJkyskSfo9oBUB/fr16+vUfVUUhaamJnw+X8riJSUlaaHDw8M4nc4kWzAYTNomAIvFIuzYsePvgF7MysqyVFRUFKqdbW1tdHd3pwVYrda09pm1ACDLckrGAKqqqr4FFmh37979l4KCAlFRFFpbW3E4HCkpAtDr9SxatCjF7vF46OnpSbGnWwOgsrJSB3ynlSTp28nJycR5/dqEoqKitBXd2tpKPJ56LSuKkjZii8UiZGVlWUWz2fwbv9+fBJ1+pFQtXbo0xfbu3TtcLhcA8+fPT5ony3LaIERRZMmSJUtEILeoqIjt27djtVrZtm0bmzdvTpmwePHilIju3buHoigIgsCmTZuS+mOxGJFIJGUOQFZWlln0+/1+gMrKSo4ePUp1dXVKRQuCQEFBQZKts7OTgYEBABYuXMiKFStQT4YKmX6JuN1uLl26xPj4OH19fV7t8PDwwMzoPB5PUttoNJKTk5Noj42Ncf/+/YRTW7duJScnB51Ol7Tfb9++JT8/n66uLux2O9FolIGBAWV8fNyjffz4cWcoFKpVFw6FQoRCoSSwwWBg+jlvbm5ORFNcXMzy5csRBAFJknj//n1int1ux+FwMDU1BYDJZKKvr08B3oo+n8/e3t6eOISRSCSlGqcXSUdHR6KgNBoNO3fuTDhVXl6eNE+W5QRUEASqq6ux2+2fAIcIDLW3t7vUwRqNJmmvAD5+/Mjg4CBOp5MHDx4kHKmoqKCwMHH3sG7dOpYtW8ZMZWdns2fPHsrKyrDb7Z3AkABo9Xr93q6urv+uXr1alGWZc+fOpaR7eqrhc0GdOHECrVabkp1Xr17hdruRZZkFCxZQWlqKwWDg6tWr0fr6+v3ATxpAjsfj/YFA4Pu9e/cWCILA0NAQXq83xXNVeXl5HDlyJKngpjsoSRIlJSVYrVYKCwvR6XSMjo5SW1vbMTExcQH4pD4EYi9fvnxZWFj457Vr1+osFgvPnj1LuX/h8xfq8OHD5Ofnf9WxmZJlmQMHDow9efLkCOAGFBWs8Hmv+8vLy3etWrVKLC4uxuv1MjExgSAImEwmNmzYwL59+8jLy8sYCnD27NlPN27cqAMcTHv+TNcci8VypqWlJaK+FgOBgDIyMqJEo9FZvzZjsZhy5syZSeBvpHnwpcA1Gs2fLl68OBaJRGYNU+Xz+eRdu3YNA3/MBKpKD5SVlpb+3NjYGI7FYhkDg8Ggcvny5U+SJDUDZcziXa1K5PPfQGVZWdnPp0+fnujo6IgHAoEU2ODgoGyz2WKHDh0as1gsTcAWfuVPQvhaxzRpAB1gBNZ9iUISRfGbLzfcIDAMvACeABNk8O/0PwJCxMb99V7LAAAAAElFTkSuQmCC', 'youtube': 'iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMNwAADDcBracSlQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKkSURBVEiJxZcxSBthFIC/918uGhxMsyptcGjoIgGHW9wSihQKGZrNthHsIC7S1TqWgkRwcZV2lKo0FouixaEuEQ4khIIdrClkEoIZgiae93fQgFgll5jqt93x3v++e3f/3TvhGgYHBx/UarUUEAMeA48A/3WxDagBf4A9EdmsVqsfd3d3j64GyeWDZDJpFAqFKWAC6G6haCPKIjKTzWbfA+4/Ev39/V2dnZ3LwNP/UPwqaycnJy9yuVwFQF2cVIFA4PMdCQAMBQKBL8lk0gAwACzLmtJav7kjgTp95XK5ViwWf0g0Gg36/f7fQLBRltYaEWkU5hkRKTmO06dM03ztRaAuEQ6H0Vq3RUJrHTIM46XR29v7jvNt2BClFEtLS0QiEfb39ymVSrfujIg4Cog0mxiPx1lYWGBycpKenh5c122cdANa64gCHra6QCKRYHl5mfHxcYLBII7jtLJMWAEdrUrUSaVSrK6uMjo6SigU4uzsrJn0DtU4xhs+n4+xsTFWVlYYHh6mq6vL821qm0Qd0zSZmJggk8kQi8XuR6LO1tYW+XzeUzd87S6ey+WYnZ0ln88jIijV+DrbJnF4eMj09DTb29u4rtvU+8MHVLnFDjk+PiadTrO+vs7p6WkrS1R9QAGPb8zLaK2Zm5tjcXGRSqXiqe03sO8D9pqVyGQyzM/PUywWMQzjNgIAv3xa600Ree4l2nEcRkZGODg4QCmFYRi3KQ6AiGzIwMBAt2EYB9znp9y27bLWesZjUtsELkjbtl2ur6osy/qqtX7W7io3ISIb2Wx2CHDrT5TrOE4SWLsjgW+O4yS4mLiv9ldZljWptX6Lx2mrSY6A9M7OzgeuG/kvE41Gg6ZpvhKROPCE85mj5Z8fEfnpuu5313U/2bZdvhr0F9Fo9phaoDu9AAAAAElFTkSuQmCC' } footer = '''<div align="right"> <p align="right"><b>''' + self.tr( 'Author: Leandro Franca', 'Autor: Leandro França' ) + '''</b></p> <div align="right"> <a target="_blank" rel="noopener noreferrer" href="https://www.udemy.com/user/leandro-luiz-silva-de-franca/"><img title="Udemy" src="data:image/png;base64,''' + dic_BW[ 'udemy'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/GEOCAPT/"><img title="Facebook" src="data:image/png;base64,''' + dic_BW[ 'face'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/channel/UCLrewDGciytcBG9r0OxTW2w"><img title="Youtube" src="data:image/png;base64,''' + dic_BW[ 'youtube'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.researchgate.net/profile/Leandro_Franca2"><img title="ResearchGate" src="data:image/png;base64,''' + dic_BW[ 'RG'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://github.com/LEOXINGU"><img title="GitHub" src="data:image/png;base64,''' + dic_BW[ 'github'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.linkedin.com/in/leandro-fran%C3%A7a-93093714b/"><img title="Linkedin" src="data:image/png;base64,''' + dic_BW[ 'linkedin'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="http://lattes.cnpq.br/8559852745183879"><img title="Lattes" src="data:image/png;base64,''' + dic_BW[ 'lattes'] + '''"></a> </div> </div>''' if self.LOC == 'pt': return txt_pt + footer else: return self.tr(txt_en) + footer def initAlgorithm(self, config=None): # 'INPUTS' self.addParameter( QgsProcessingParameterFeatureSource( 'INPUT1', self.tr('Boundary Survey Points', 'Pontos de Limite'), types=[QgsProcessing.TypeVectorPoint])) self.addParameter( QgsProcessingParameterFeatureSource( 'INPUT2', self.tr('Neighborhood Dividing Line', 'Elemento Confrontante'), types=[QgsProcessing.TypeVectorLine])) self.addParameter( QgsProcessingParameterFeatureSource( 'INPUT3', self.tr('Property Polygon', 'Área do Imóvel'), types=[QgsProcessing.TypeVectorPolygon])) # 'OUTPUTS' self.addParameter( QgsProcessingParameterFileDestination( 'HTML', self.tr('Descriptive Memorial', 'Memorial Descritivo'), self.tr('HTML files (*.html)'))) # Acentos para HTML def str2HTML(self, texto): if texto: dicHTML = { 'Á': 'Á', 'á': 'á', 'Â': 'Â', 'â': 'â', 'À': 'À', 'à': 'à', 'Å': 'Å', 'å': 'å', 'Ã': 'Ã', 'ã': 'ã', 'Ä': 'Ä', 'ä': 'ä', 'Æ': 'Æ', 'æ': 'æ', 'É': 'É', 'é': 'é', 'Ê': 'Ê', 'ê': 'ê', 'È': 'È', 'è': 'è', 'Ë': 'Ë', 'ë': 'Ë', 'Ð': 'Ð', 'ð': 'ð', 'Í': 'Í', 'í': 'í', 'Î': 'Î', 'î': 'î', 'Ì': 'Ì', 'ì': 'ì', 'Ï': 'Ï', 'ï': 'ï', 'Ó': 'Ó', 'ó': 'ó', 'Ô': 'Ô', 'ô': 'ô', 'Ò': 'Ò', 'ò': 'ò', 'Ø': 'Ø', 'ø': 'ø', 'Ù': 'Ù', 'ù': 'ù', 'Ü': 'Ü', 'ü': 'ü', 'Ç': 'Ç', 'ç': 'ç', 'Ñ': 'Ñ', 'ñ': 'ñ', 'Ý': 'Ý', 'ý': 'ý', '"': '"', '”': '"', '<': '<', '>': '>', '®': '®', '©': '©', '\'': ''', 'ª': 'ª', 'º': 'º', '°': '°' } for item in dicHTML: if item in texto: texto = texto.replace(item, dicHTML[item]) return texto else: return '' # Fuso e Hemisfério def FusoHemisf(self, pnt): lon = pnt.x() lat = pnt.y() # Calculo do Fuso fuso = round((183 + lon) / 6.0) # Hemisferio hemisf = 'N' if lat >= 0 else 'S' return (hemisf, fuso) # Cálculo de Azimutes def azimute(self, A, B): # Cálculo dos Azimutes entre dois pontos (Vetor AB origem A extremidade B) if ((B.x() - A.x()) >= 0 and (B.y() - A.y()) > 0): #1º quadrante AzAB = atan((B.x() - A.x()) / (B.y() - A.y())) AzBA = AzAB + pi elif ((B.x() - A.x()) > 0 and (B.y() - A.y()) < 0): #2º quadrante AzAB = pi + atan((B.x() - A.x()) / (B.y() - A.y())) AzBA = AzAB + pi elif ((B.x() - A.x()) <= 0 and (B.y() - A.y()) < 0): #3º quadrante AzAB = atan((B.x() - A.x()) / (B.y() - A.y())) + pi AzBA = AzAB - pi elif ((B.x() - A.x()) < 0 and (B.y() - A.y()) > 0): #4º quadrante AzAB = 2 * pi + atan((B.x() - A.x()) / (B.y() - A.y())) AzBA = AzAB + pi elif ((B.x() - A.x()) > 0 and (B.y() - A.y()) == 0): # no eixo positivo de x (90º) AzAB = pi / 2 AzBA = 1.5 * pi else: # ((B.x()-A.x())<0 and(B.y()-A.y())==0) # no eixo negativo de x (270º) AzAB = 1.5 * pi AzBA = pi / 2 # Correção dos ângulos para o intervalo de 0 a 2pi if AzAB < 0 or AzAB > 2 * pi: if (AzAB < 0): AzAB = AzAB + 2 * pi else: AzAB = AzAB - 2 * pi if AzBA < 0 or AzBA > 2 * pi: if (AzBA < 0): AzBA = AzBA + 2 * pi else: AzBA = AzBA - 2 * pi return (AzAB, AzBA) # Graus Decimais para DMS def dd2dms(self, dd, n_digits): if dd != 0: graus = int(floor(abs(dd))) resto = round(abs(dd) - graus, 10) if dd < 0: texto = '-' + str(graus) + '°' else: texto = str(graus) + '°' minutos = int(floor(60 * resto)) resto = round(resto * 60 - minutos, 10) texto = texto + '{:02d}'.format(minutos) + "'" segundos = resto * 60 if n_digits < 1: texto = texto + '{:02d}'.format(int(segundos)) + '"' else: texto = texto + ('{:0' + str(3 + n_digits) + '.' + str(n_digits) + 'f}').format(segundos) + '"' return texto else: return "0°00'" + ('{:0' + str(3 + n_digits) + '.' + str(n_digits) + 'f}').format(0) def processAlgorithm(self, parameters, context, feedback): vertices = self.parameterAsSource(parameters, 'INPUT1', context) limites = self.parameterAsSource(parameters, 'INPUT2', context) area = self.parameterAsSource(parameters, 'INPUT3', context) meses = { 1: 'janeiro', 2: 'fevereiro', 3: 'março', 4: 'abril', 5: 'maio', 6: 'junho', 7: 'julho', 8: 'agosto', 9: 'setembro', 10: 'outubro', 11: 'novembro', 12: 'dezembro' } # VALIDAÇÃO DOS DADOS DE ENTRADA!!! # atributos codigo deve ser preenchido # ordem do numeros # Pegando informações dos confrontantes (limites) ListaDescr = [] ListaCont = [] soma = 0 for linha in limites.getFeatures(): Lin_coord = linha.geometry().asMultiPolyline()[0] ListaDescr += [[ self.str2HTML(linha['descr_pnt_inicial']), self.str2HTML(linha['confrontante']) ]] cont = len(Lin_coord) ListaCont += [(soma, cont - 1)] soma += cont - 1 # Pegando o SRC do Projeto SRC = QgsProject.instance().crs().description() # Verificando o SRC if QgsProject.instance().crs().isGeographic(): raise QgsProcessingException( self.tr('The Project CRS must be projected!', 'O SRC do Projeto deve ser Projetado!')) feedback.pushInfo( self.tr('Project CRS is {}.', 'SRC do Projeto é {}.').format(SRC)) # Dados do levantamento #Fields = area.fields() #fieldnames = [field.name() for field in Fields] for feat in area.getFeatures(): feat1 = feat break geom = feat1.geometry() centroideG = geom.centroid().asPoint() # Transformar Coordenadas de Geográficas para o sistema UTM coordinateTransformer = QgsCoordinateTransform() coordinateTransformer.setDestinationCrs(QgsProject.instance().crs()) coordinateTransformer.setSourceCrs( QgsCoordinateReferenceSystem('EPSG:4674')) pnts = {} for feat in vertices.getFeatures(): geom = feat.geometry() if geom.isMultipart(): pnts[feat['ordem']] = [ coordinateTransformer.transform(geom.asMultiPoint()[0]), feat['tipo'], feat['codigo'] ] else: pnts[feat['ordem']] = [ coordinateTransformer.transform(geom.asPoint()), feat['tipo'], feat['codigo'] ] # Cálculo dos Azimutes e Distâncias tam = len(pnts) Az_lista, Dist = [], [] for k in range(tam): pntA = pnts[k + 1][0] pntB = pnts[max((k + 2) % (tam + 1), 1)][0] Az_lista += [(180 / pi) * self.azimute(pntA, pntB)[0]] Dist += [sqrt((pntA.x() - pntB.x())**2 + (pntA.y() - pntB.y())**2)] # Inserindo dados iniciais do levantamento itens = { '[IMOVEL]': self.str2HTML(feat1['imóvel']), '[PROPRIETARIO]': self.str2HTML(feat1['proprietário']), '[UF]': feat1['UF'], '[MATRICULAS]': self.str2HTML(feat1['matrícula']), '[AREA]': '{:,.2f}'.format(feat1['area']).replace(',', 'X').replace( '.', ',').replace('X', '.'), '[SRC]': SRC, '[COMARCA]': self.str2HTML(feat1['município'] + ' - ' + feat1['UF']), '[MUNICIPIO]': self.str2HTML(feat1['município']), '[PERIMETRO]': '{:,.2f}'.format(feat1['perimetro']).replace(',', 'X').replace( '.', ',').replace('X', '.') } for item in itens: self.texto_inicial = self.texto_inicial.replace(item, itens[item]) LINHAS = self.texto_inicial #feedback.pushInfo(str(ListaCont)) for w, t in enumerate(ListaCont): linha0 = self.texto_var1 itens = { '[Vn]': pnts[t[0] + 1][2], '[En]': '{:,.2f}'.format(pnts[t[0] + 1][0].x()).replace( ',', 'X').replace('.', ',').replace('X', '.'), '[Nn]': '{:,.2f}'.format(pnts[t[0] + 1][0].y()).replace( ',', 'X').replace('.', ',').replace('X', '.'), '[Az_n]': self.str2HTML( self.dd2dms(Az_lista[t[0]], 2).replace('.', ',')), '[Dist_n]': '{:,.2f}'.format(Dist[t[0]]).replace(',', 'X').replace( '.', ',').replace('X', '.'), '[Descr_k]': ListaDescr[w][0], '[Confront_k]': ListaDescr[w][1] } for item in itens: linha0 = linha0.replace(item, itens[item]) LINHAS += linha0 LIN0 = '' for k in range(t[0] + 1, t[0] + t[1]): linha1 = self.texto_var2 itens = { '[Vn]': pnts[k + 1][2], '[En]': '{:,.2f}'.format(pnts[k + 1][0].x()).replace( ',', 'X').replace('.', ',').replace('X', '.'), '[Nn]': '{:,.2f}'.format(pnts[k + 1][0].y()).replace( ',', 'X').replace('.', ',').replace('X', '.'), '[Az_n]': self.str2HTML( self.dd2dms(Az_lista[k], 2).replace('.', ',')), '[Dist_n]': '{:,.2f}'.format(Dist[k]).replace(',', 'X').replace( '.', ',').replace('X', '.') } for item in itens: linha1 = linha1.replace(item, itens[item]) LIN0 += linha1 LINHAS += LIN0 # Inserindo dados finais itens = { '[P-01]': pnts[1][2], '[N1]': '{:,.2f}'.format(pnts[1][0].y()).replace(',', 'X').replace( '.', ',').replace('X', '.'), '[E1]': '{:,.2f}'.format(pnts[1][0].x()).replace(',', 'X').replace( '.', ',').replace('X', '.'), '[FUSO]': str(self.FusoHemisf(centroideG)[1]), '[HEMISFERIO]': self.FusoHemisf(centroideG)[0], '[RESP_TEC]': self.str2HTML(feat1['Resp_Tecnico']), '[CREA]': self.str2HTML(feat1['CREA']), '[LOCAL]': self.str2HTML((feat1['município']).title() + ' - ' + (feat1['UF']).upper()), '[DATA]': ((feat1['data_levantamento'].toPyDate()).strftime("%d de {} de %Y") ).format(meses[feat1['data_levantamento'].month()]) } for item in itens: self.texto_final = self.texto_final.replace(item, itens[item]) LINHAS += self.texto_final output = self.parameterAsFileOutput(parameters, self.HTML, context) arq = open(output, 'w') arq.write(LINHAS) arq.close() # Check for cancelation if feedback.isCanceled(): return {} feedback.pushInfo(self.tr('Operation completed successfully!')) feedback.pushInfo('Leandro França - Eng Cart') return {self.HTML: output}
class ImportPhotos(QgsProcessingAlgorithm): LOC = QgsApplication.locale() def translate(self, string): return QCoreApplication.translate('Processing', string) def tr(self, *string): # Traduzir para o portugês: arg[0] - english (translate), arg[1] - português if self.LOC == 'pt': if len(string) == 2: return string[1] else: return self.translate(string[0]) else: return self.translate(string[0]) def createInstance(self): return ImportPhotos() def name(self): return 'importphotos' def displayName(self): return self.tr('Photos with Geotag', 'Fotos com Geotag') def group(self): return self.tr('LF Reambulation', 'LF Reambulação') def groupId(self): return 'lf_reambulation' def tags(self): return self.tr('import', 'photo', 'reambulation', 'geotag', 'geophoto', 'reambulação', 'fotografia', 'photography').split(',') def shortHelpString(self): txt_en = 'Imports photos with geotag to a Point Layer.' txt_pt = 'Importa fotos com geotag para uma camada de pontos.' dic_BW = { 'face': 'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMwAADDMBUlqVhwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIUSURBVEiJvZa9quJAGIbfMfEYTUSUQAqLYOnehJobsBTlHLbRQtKKlY3lObegxRa7pRdg7y0saiuoKAErMZif2Squ2eTEOCfsC1Pk+3uYb2YyQwCg1+u9UUqHAKoAOCQrB8ASwPt0Ov1JdF3/bprmj4QhoXp5eXnjTdMcUEr/Bw+WZQ15Smn1q4UIIZBlGaIoghBys2+3W1yv19u367rfeAAc6ww5jkOz2USj0YAoigH/aDTCbrfzpfCUUrAC2+02NE2LjPm3NjNQkiTU6/WHsFAgi1RVRSqVCthd171BwmozA/P5fMA2n88xm81g2zYAwHGccCAL9H43elosFrhcLpE5zMCwHMdxImtRSp8DptNpZDIZAIAgCAG/IAi+42Ga5q29nkin06FxgZqmodvtxooFgPF4jPV67bM9NcNnW384HJI7h49kWRZOp9PXgOfzGfv9HgCQy+VQKBR8fsMwYFkWAOB4PMJ13UAN0mq1Yq/hfVytVoOu6z7/YDDAZrP5Wzzk6CR6LOLEJLqGcWrxYX2OW5wJmOQOjQX0ApOERgIrlQoTUJblgK1cLodeWZ4IIeDDngZx5P1T75XNZiFJUmQeTyl1wPAW/awrD7rlpDiOW3qL/cz4DBY1CCG/U4qifDw7O1YpivJBAGAymbwahjG0bbtKKeXjJJdKJaiq6rOtVqvAjU8IsTmOWxaLxfd+v//rD1H2cZ8dKhk8AAAAAElFTkSuQmCC', 'github': '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', 'instagram': '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', 'lattes': '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', 'linkedin': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6QAADOkBmiiHWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJRSURBVEiJ7ZU/aCJREMa/t7soa5LOoGihktZOQSxSWykBIYVaWZ6NVa6wSZ/WI5BGziJypA1CQBLsgkKKgBjFQkEtkouJ+AdxdeeKnHvurXdcXK84uK/amfl4v9m3s++xbrdrury8PGm324dEZMYGxRj7arPZvoRCoSPh/Pz8pFqtftgkYEnmTqeT6PV6xDscjs9EZPpLIADAy8uLS5jP52bGGACA4ziEw2H4/X5IkoSrqytcX1/rBhHRrrCcCAaDCAQCShyJRPD6+oq7uzvdMG458Hg8GoPX69UN0YDG47HGsCqnG5TP50FESjyZTFAoFDYCYvF4nBbDAAB7e3vw+XyQJAnFYhGPj4+6IUQE4eekJEm4vb0F8DaFC1mtVphMb3+BLMtotVogItjtdjgcDhiNRvT7fTw8PKzcbhXI5XIhlUqpOkkkEpjP5zg+PoYg/LCfnp5if38fbrdbteB0OsXFxQVubm5+DTIYDKoiYww8z4OIwPO8qhaLxbCzs6Pp3GAwIBqN4vn5Gff390qe0zj/UKsgywqFQqpY843eo1KphHK5DLPZjIODAxiNRqXmdDqxvb2N4XCoD1Sv13F2dqbEs9kM0WhU5bFYLApo7a1bTOZClUpF49na2lKe1wb1ej1VvGqklwdobdB79R/0j4FkWdYYiEh1dawrAcATgF0AaDabyOVyyuE5HA4xmUwAAJlMRjl2ZFlGo9FQLTQajZDNZiGKouKp1WqL8hNLJpPpwWCQ0N3ybySKYpqLxWJHjLFP399s03riOC4dCAQ+fgMeouMzfwx22gAAAABJRU5ErkJggg==', 'RG': 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAcCAYAAAB2+A+pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMfwAADH8BdgxfmQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM2SURBVEiJtZdLSytJFMd/1dXB+OiQRJEQBEnbPgISJGIQcePKjyBZzoP5AH6OuR9gFjPMznwC1650EbKSy00WPhJ8EMlDtG1M0p2axZCA1871cZM/NDRFnfqdqjrnVJUAODg4+E0IsQ8sA5LRyANKQogve3t7/4hcLvcH8NeIYL5SSv2uAftDHhSl1A/7CCH2dWBxWNBoNIppmgSDQarVKufn53ie59d1RQO0YUBjsRg7OztomkatVmNpaYnNzU2EEH7dNX0YUKUUpmlyd3dHPp9HKcXV1RXT09MIIXyXfihgKSWGYVCpVPoQ27axbXugjS/4HcHh29btdlFKsbq6SiwWA6BQKHB/f/82WEpJKpUiEAi8aA8EAiilaLVaNBoNrq+vabfbr+BCCG5vb3l8fCSTyaDr/ov6KrA8z6NcLtNqtUgkEszPz+M4Ds1mE9u2MQyDjY0Ndnd3mZmZ6ds4jkMoFAKg0Wjw8PCAEIJOp+ML9nWnZ5hIJJBSUiqV+gMIIbAsi3Q6zdbWFoeHh7iuS7lcZn19HcdxsG0by7Ko1+sD93lgcCml6Ha7SClftZ+dnbG4uIhhGMzOznJzc0OlUkHTNBYWFtB1nXq9zunp6aA8/lxUe57H09MThmEwPj7ed+ji4oLLy0uEEHieNyiHPw+WUjI5OYlS6lXE9krmj6DwyaplmiaGYVCtVqnX658Z4u0ZCyGIx+O0223GxsaYm5sjHo9Tq9U4OTn5FPRdYCkly8vLCCEIh8MopSgUCpTLZVzXHR3YdV2Ojo7wPI/t7W1isRjBYPCnoPDOPVZK4XlePz2SySThcHj04J4ajQbFYhEpJZlM5lWOjwwMUCwWaTabRCIR0un08MG9gt/778l1XfL5PJ1OB9M0WVlZGR54amoKy7IIBoPouo5lWYRCof7SNptN8vk83W6XVCrF2toaExMTHwKLXC734vCVUpJOp9F1/cW5rGkapVLpRcGIRqMkk0kikQiO43B8fMzz8/O7wd73Mx90EfArg0opNE178/LwnboaUPID+H2DnPkgFOCbppT68lGrn5VS6k8tm83+DfwKfOX/Z8ao5AFflVK/ZLPZf/8DudZq3wvXLmgAAAAASUVORK5CYII=', 'tweeter': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMQAADDEBLaRWDgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK5SURBVEiJpZU7T+NAFEZP4kAePBwZ8TA0EUIRKKIgQhSImnZ/wDYr7Q/barddbRu2QVAQhChAgBQqQClwFEIcx8IYfLdKNk5sJ4GRRh6PPN+Z+90749jZ2VnGsqyfwD6QEREARISocdRcT7dF5AD4lmi327+AL0GCn4QgIhkR+SIiPxIish8k3i/yQVCn7ydEJD0sgjDBMUCZxCg2hQmqqsri4iKKotBoNKhWq741vesSvULpdJrJyUkajcZQy7a2tlheXqa3FQoFzs/PmZubQ9M0Dg8Pu2vivQJLS0sUi0Wy2WykFfl8fgACkEql2N3dJZfLcXFxgaqq/0G9O04mk8RiMba3t8nlcqHRrK6uDkB628TEBDs7O5imORgRgGVZ3Y/z+Tx7e3ssLCz4QMlkkng8HglqNpscHBzw9vbmz1EHVK1WWVtb6wpNTU1RLBZ5f3/HMAzq9TqO40RCAGq1Gq7r+jboK4aZmRmurq7Y3Nz0LVQUBV3X0XV9KATAcZwBy7vlLSJomjbU/1Ha8/PzAMhXdQ8PD5+GABiGEQ1qt9tcXl5+CvL09MTLy8ugdf0T9/f32LbNxsYGs7OzY4Our68DD/oASEQoFApMT0+PDTFNk7u7u0BQPAhULpdxXXds0PHxMZ7nDUBCQa1Wi1KpRKVSwTTNkSAnJyfU6/XQWz4QJCI4jsPj4yOKogyFnJ6ecnt7G3nTd3OUSCSYn59HURRUVUXXdTKZTCTAtm2Ojo585dwP6rx3Qa+vrzSbTdbX11lZWSEWi4UCLMvi5uaGSqWC53mh/67esa/qTNOkXC4DoGka2WyWVCoFgOu6tFotDMPAtu3QXISNA8tbRKjVaoEnPCwPYZZ1nnHP8+ww2Ed7P0RE7LjneX/7ff6ocES0pbiIfBWRP57n2aMAwywKGdsi8ltRlO//AFPkniYXwGRMAAAAAElFTkSuQmCC', 'udemy': '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', 'youtube': 'iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMNwAADDcBracSlQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKkSURBVEiJxZcxSBthFIC/918uGhxMsyptcGjoIgGHW9wSihQKGZrNthHsIC7S1TqWgkRwcZV2lKo0FouixaEuEQ4khIIdrClkEoIZgiae93fQgFgll5jqt93x3v++e3f/3TvhGgYHBx/UarUUEAMeA48A/3WxDagBf4A9EdmsVqsfd3d3j64GyeWDZDJpFAqFKWAC6G6haCPKIjKTzWbfA+4/Ev39/V2dnZ3LwNP/UPwqaycnJy9yuVwFQF2cVIFA4PMdCQAMBQKBL8lk0gAwACzLmtJav7kjgTp95XK5ViwWf0g0Gg36/f7fQLBRltYaEWkU5hkRKTmO06dM03ztRaAuEQ6H0Vq3RUJrHTIM46XR29v7jvNt2BClFEtLS0QiEfb39ymVSrfujIg4Cog0mxiPx1lYWGBycpKenh5c122cdANa64gCHra6QCKRYHl5mfHxcYLBII7jtLJMWAEdrUrUSaVSrK6uMjo6SigU4uzsrJn0DtU4xhs+n4+xsTFWVlYYHh6mq6vL821qm0Qd0zSZmJggk8kQi8XuR6LO1tYW+XzeUzd87S6ey+WYnZ0ln88jIijV+DrbJnF4eMj09DTb29u4rtvU+8MHVLnFDjk+PiadTrO+vs7p6WkrS1R9QAGPb8zLaK2Zm5tjcXGRSqXiqe03sO8D9pqVyGQyzM/PUywWMQzjNgIAv3xa600Ree4l2nEcRkZGODg4QCmFYRi3KQ6AiGzIwMBAt2EYB9znp9y27bLWesZjUtsELkjbtl2ur6osy/qqtX7W7io3ISIb2Wx2CHDrT5TrOE4SWLsjgW+O4yS4mLiv9ldZljWptX6Lx2mrSY6A9M7OzgeuG/kvE41Gg6ZpvhKROPCE85mj5Z8fEfnpuu5313U/2bZdvhr0F9Fo9phaoDu9AAAAAElFTkSuQmCC' } image = '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' footer = '''<div> <div align="center"> <img src="data:image/jpg;base64,''' + image + ''' </div> <div align="right"> <p align="right"> <b>''' + self.tr( 'Author: Leandro Franca', 'Autor: Leandro França' ) + '''</b> </p> <a target="_blank" rel="noopener noreferrer" href="https://www.udemy.com/user/leandro-luiz-silva-de-franca/"><img title="Udemy" src="data:image/png;base64,''' + dic_BW[ 'udemy'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/GEOCAPT/"><img title="Facebook" src="data:image/png;base64,''' + dic_BW[ 'face'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/channel/UCLrewDGciytcBG9r0OxTW2w"><img title="Youtube" src="data:image/png;base64,''' + dic_BW[ 'youtube'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.researchgate.net/profile/Leandro_Franca2"><img title="ResearchGate" src="data:image/png;base64,''' + dic_BW[ 'RG'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://github.com/LEOXINGU"><img title="GitHub" src="data:image/png;base64,''' + dic_BW[ 'github'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.linkedin.com/in/leandro-fran%C3%A7a-93093714b/"><img title="Linkedin" src="data:image/png;base64,''' + dic_BW[ 'linkedin'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="http://lattes.cnpq.br/8559852745183879"><img title="Lattes" src="data:image/png;base64,''' + dic_BW[ 'lattes'] + '''"></a> </div> </div>''' return self.tr(txt_en, txt_pt) + footer FOLDER = 'FOLDER' NONGEO = 'NONGEO' OUTPUT = 'OUTPUT' def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterFile( self.FOLDER, self.tr('Folder with JPEG photos', 'Pasta com fotos JPEG'), behavior=QgsProcessingParameterFile.Folder, defaultValue=None)) self.addParameter( QgsProcessingParameterFile( self.NONGEO, self.tr('Folder to copy the photos without geotag', 'Pasta para copiar as fotos sem geotag'), behavior=QgsProcessingParameterFile.Folder, defaultValue=None, optional=True)) self.addParameter( QgsProcessingParameterFeatureSink( self.OUTPUT, self.tr('Geolocated photos', 'Fotos Geolocalizadas'))) def processAlgorithm(self, parameters, context, feedback): pasta = self.parameterAsFile(parameters, self.FOLDER, context) if not pasta: raise QgsProcessingException( self.invalidSourceError(parameters, self.FOLDER)) fotos_nao_geo = self.parameterAsFile(parameters, self.NONGEO, context) lista = os.listdir(pasta) tam = len(lista) copy_ngeo = False if os.path.isdir(fotos_nao_geo): copy_ngeo = True # Funcao para transformar os dados do EXIF em coordenadas em graus decimais def coordenadas(exif): try: ref_lat = exif['GPSInfo'][1][0] ref_lon = exif['GPSInfo'][3][0] sinal_lat, sinal_lon = 0, 0 if ref_lat == 'S': sinal_lat = -1 elif ref_lat == 'N': sinal_lat = 1 if ref_lon == 'W': sinal_lon = -1 elif ref_lon == 'E': sinal_lon = 1 grausLat, grausLon = exif['GPSInfo'][2][0][0], exif['GPSInfo'][ 4][0][0] minLat, minLon = exif['GPSInfo'][2][1][0], exif['GPSInfo'][4][ 1][0] segLat = exif['GPSInfo'][2][2][0] / float( exif['GPSInfo'][2][2][1]) segLon = exif['GPSInfo'][4][2][0] / float( exif['GPSInfo'][4][2][1]) if sinal_lat != 0 and sinal_lon != 0: lat = sinal_lat * (float(grausLat) + minLat / 60.0 + segLat / 3600.0) lon = sinal_lon * (float(grausLon) + minLon / 60.0 + segLon / 3600.0) return lat, lon except: return 0, 0 # Funcao para pegar Azimute def azimute(exif): Az = exif['GPSInfo'][17] if isinstance(Az, tuple): Az = Az[0] / float(Az[1]) return Az else: return Az # Funcao para gerar o padrao data-hora def data_hora(texto): data_hora = texto.replace(' ', ':') data_hora = data_hora.split(':') ano = int(data_hora[0]) mes = int(data_hora[1]) dia = int(data_hora[2]) hora = int(data_hora[3]) minuto = int(data_hora[4]) segundo = int(data_hora[5]) data_hora = unicode( datetime.datetime(ano, mes, dia, hora, minuto, segundo)) return data_hora # Criando Output crs = QgsCoordinateReferenceSystem() crs.createFromSrid(4326) fields = QgsFields() fields.append(QgsField(self.tr('name', 'nome'), QVariant.String)) fields.append(QgsField(self.tr('azimuth', 'azimute'), QVariant.Int)) fields.append( QgsField(self.tr('date_time', 'data_hora'), QVariant.String)) fields.append(QgsField(self.tr('path', 'caminho'), QVariant.String)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, crs) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) Percent = 100.0 / tam if tam != 0 else 0 for index, arquivo in enumerate(lista): if (arquivo).lower().endswith(('.jpg', '.jpeg')): img = PIL.Image.open(os.path.join(pasta, arquivo)) if img._getexif(): exif = { PIL.ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in PIL.ExifTags.TAGS } else: exif = {} lon, lat = 0, 0 Az = None date_time = None if 'GPSInfo' in exif: lat, lon = coordenadas(exif) if 17 in exif['GPSInfo']: Az = azimute(exif) if 'DateTimeOriginal' in exif: date_time = data_hora(exif['DateTimeOriginal']) elif 'DateTime' in exif: date_time = data_hora(exif['DateTime']) if lon != 0: feature = QgsFeature(fields) feature.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(lon, lat))) feature.setAttributes( [arquivo, Az, date_time, os.path.join(pasta, arquivo)]) sink.addFeature(feature, QgsFeatureSink.FastInsert) else: print() feedback.pushInfo( self.tr( 'The file "{}" has no geotag!'.format(arquivo), 'A imagem "{}" não possui geotag!'.format( arquivo))) if copy_ngeo: shutil.copy2(os.path.join(pasta, arquivo), os.path.join(fotos_nao_geo, arquivo)) if feedback.isCanceled(): break feedback.setProgress(int((index + 1) * Percent)) feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo( self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart')) return {self.OUTPUT: dest_id}
def initGui(self): if QgsApplication.locale() in ['fr','FR']: self.switchLang('fr') self.initProcessing()
class InventoryRaster(QgsProcessingAlgorithm): LOC = QgsApplication.locale() def translate(self, string): return QCoreApplication.translate('Processing', string) def tr(self, *string): # Traduzir para o portugês: arg[0] - english (translate), arg[1] - português if self.LOC == 'pt': if len(string) == 2: return string[1] else: return self.translate(string[0]) else: return self.translate(string[0]) def createInstance(self): return InventoryRaster() def name(self): return 'inventoryraster' def displayName(self): return self.tr('Raster data inventory', 'Inventário de dados raster') def group(self): return self.tr('LF Raster') def groupId(self): return 'lf_raster' def shortHelpString(self): txt_en = 'Creates a vector layer with the inventory of raster files in a folder. The geometry type of the features of this layer can be Polygon (bounding box) or Point (centroid).' txt_pt = 'Cria uma camada vetorial com o inventário de arquivos raster de uma pasta. O tipo de geometria das feições dessa camada pode ser Polígono (retângulo envolvente) ou Ponto (centroide).' dic_BW = { 'face': 'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMwAADDMBUlqVhwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIUSURBVEiJvZa9quJAGIbfMfEYTUSUQAqLYOnehJobsBTlHLbRQtKKlY3lObegxRa7pRdg7y0saiuoKAErMZif2Squ2eTEOCfsC1Pk+3uYb2YyQwCg1+u9UUqHAKoAOCQrB8ASwPt0Ov1JdF3/bprmj4QhoXp5eXnjTdMcUEr/Bw+WZQ15Smn1q4UIIZBlGaIoghBys2+3W1yv19u367rfeAAc6ww5jkOz2USj0YAoigH/aDTCbrfzpfCUUrAC2+02NE2LjPm3NjNQkiTU6/WHsFAgi1RVRSqVCthd171BwmozA/P5fMA2n88xm81g2zYAwHGccCAL9H43elosFrhcLpE5zMCwHMdxImtRSp8DptNpZDIZAIAgCAG/IAi+42Ga5q29nkin06FxgZqmodvtxooFgPF4jPV67bM9NcNnW384HJI7h49kWRZOp9PXgOfzGfv9HgCQy+VQKBR8fsMwYFkWAOB4PMJ13UAN0mq1Yq/hfVytVoOu6z7/YDDAZrP5Wzzk6CR6LOLEJLqGcWrxYX2OW5wJmOQOjQX0ApOERgIrlQoTUJblgK1cLodeWZ4IIeDDngZx5P1T75XNZiFJUmQeTyl1wPAW/awrD7rlpDiOW3qL/cz4DBY1CCG/U4qifDw7O1YpivJBAGAymbwahjG0bbtKKeXjJJdKJaiq6rOtVqvAjU8IsTmOWxaLxfd+v//rD1H2cZ8dKhk8AAAAAElFTkSuQmCC', 'github': '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', 'instagram': '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', 'lattes': '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', 'linkedin': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6QAADOkBmiiHWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJRSURBVEiJ7ZU/aCJREMa/t7soa5LOoGihktZOQSxSWykBIYVaWZ6NVa6wSZ/WI5BGziJypA1CQBLsgkKKgBjFQkEtkouJ+AdxdeeKnHvurXdcXK84uK/amfl4v9m3s++xbrdrury8PGm324dEZMYGxRj7arPZvoRCoSPh/Pz8pFqtftgkYEnmTqeT6PV6xDscjs9EZPpLIADAy8uLS5jP52bGGACA4ziEw2H4/X5IkoSrqytcX1/rBhHRrrCcCAaDCAQCShyJRPD6+oq7uzvdMG458Hg8GoPX69UN0YDG47HGsCqnG5TP50FESjyZTFAoFDYCYvF4nBbDAAB7e3vw+XyQJAnFYhGPj4+6IUQE4eekJEm4vb0F8DaFC1mtVphMb3+BLMtotVogItjtdjgcDhiNRvT7fTw8PKzcbhXI5XIhlUqpOkkkEpjP5zg+PoYg/LCfnp5if38fbrdbteB0OsXFxQVubm5+DTIYDKoiYww8z4OIwPO8qhaLxbCzs6Pp3GAwIBqN4vn5Gff390qe0zj/UKsgywqFQqpY843eo1KphHK5DLPZjIODAxiNRqXmdDqxvb2N4XCoD1Sv13F2dqbEs9kM0WhU5bFYLApo7a1bTOZClUpF49na2lKe1wb1ej1VvGqklwdobdB79R/0j4FkWdYYiEh1dawrAcATgF0AaDabyOVyyuE5HA4xmUwAAJlMRjl2ZFlGo9FQLTQajZDNZiGKouKp1WqL8hNLJpPpwWCQ0N3ybySKYpqLxWJHjLFP399s03riOC4dCAQ+fgMeouMzfwx22gAAAABJRU5ErkJggg==', 'RG': 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAcCAYAAAB2+A+pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMfwAADH8BdgxfmQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM2SURBVEiJtZdLSytJFMd/1dXB+OiQRJEQBEnbPgISJGIQcePKjyBZzoP5AH6OuR9gFjPMznwC1650EbKSy00WPhJ8EMlDtG1M0p2axZCA1871cZM/NDRFnfqdqjrnVJUAODg4+E0IsQ8sA5LRyANKQogve3t7/4hcLvcH8NeIYL5SSv2uAftDHhSl1A/7CCH2dWBxWNBoNIppmgSDQarVKufn53ie59d1RQO0YUBjsRg7OztomkatVmNpaYnNzU2EEH7dNX0YUKUUpmlyd3dHPp9HKcXV1RXT09MIIXyXfihgKSWGYVCpVPoQ27axbXugjS/4HcHh29btdlFKsbq6SiwWA6BQKHB/f/82WEpJKpUiEAi8aA8EAiilaLVaNBoNrq+vabfbr+BCCG5vb3l8fCSTyaDr/ov6KrA8z6NcLtNqtUgkEszPz+M4Ds1mE9u2MQyDjY0Ndnd3mZmZ6ds4jkMoFAKg0Wjw8PCAEIJOp+ML9nWnZ5hIJJBSUiqV+gMIIbAsi3Q6zdbWFoeHh7iuS7lcZn19HcdxsG0by7Ko1+sD93lgcCml6Ha7SClftZ+dnbG4uIhhGMzOznJzc0OlUkHTNBYWFtB1nXq9zunp6aA8/lxUe57H09MThmEwPj7ed+ji4oLLy0uEEHieNyiHPw+WUjI5OYlS6lXE9krmj6DwyaplmiaGYVCtVqnX658Z4u0ZCyGIx+O0223GxsaYm5sjHo9Tq9U4OTn5FPRdYCkly8vLCCEIh8MopSgUCpTLZVzXHR3YdV2Ojo7wPI/t7W1isRjBYPCnoPDOPVZK4XlePz2SySThcHj04J4ajQbFYhEpJZlM5lWOjwwMUCwWaTabRCIR0un08MG9gt/778l1XfL5PJ1OB9M0WVlZGR54amoKy7IIBoPouo5lWYRCof7SNptN8vk83W6XVCrF2toaExMTHwKLXC734vCVUpJOp9F1/cW5rGkapVLpRcGIRqMkk0kikQiO43B8fMzz8/O7wd73Mx90EfArg0opNE178/LwnboaUPID+H2DnPkgFOCbppT68lGrn5VS6k8tm83+DfwKfOX/Z8ao5AFflVK/ZLPZf/8DudZq3wvXLmgAAAAASUVORK5CYII=', 'tweeter': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMQAADDEBLaRWDgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK5SURBVEiJpZU7T+NAFEZP4kAePBwZ8TA0EUIRKKIgQhSImnZ/wDYr7Q/barddbRu2QVAQhChAgBQqQClwFEIcx8IYfLdKNk5sJ4GRRh6PPN+Z+90749jZ2VnGsqyfwD6QEREARISocdRcT7dF5AD4lmi327+AL0GCn4QgIhkR+SIiPxIish8k3i/yQVCn7ydEJD0sgjDBMUCZxCg2hQmqqsri4iKKotBoNKhWq741vesSvULpdJrJyUkajcZQy7a2tlheXqa3FQoFzs/PmZubQ9M0Dg8Pu2vivQJLS0sUi0Wy2WykFfl8fgACkEql2N3dJZfLcXFxgaqq/0G9O04mk8RiMba3t8nlcqHRrK6uDkB628TEBDs7O5imORgRgGVZ3Y/z+Tx7e3ssLCz4QMlkkng8HglqNpscHBzw9vbmz1EHVK1WWVtb6wpNTU1RLBZ5f3/HMAzq9TqO40RCAGq1Gq7r+jboK4aZmRmurq7Y3Nz0LVQUBV3X0XV9KATAcZwBy7vlLSJomjbU/1Ha8/PzAMhXdQ8PD5+GABiGEQ1qt9tcXl5+CvL09MTLy8ugdf0T9/f32LbNxsYGs7OzY4Our68DD/oASEQoFApMT0+PDTFNk7u7u0BQPAhULpdxXXds0PHxMZ7nDUBCQa1Wi1KpRKVSwTTNkSAnJyfU6/XQWz4QJCI4jsPj4yOKogyFnJ6ecnt7G3nTd3OUSCSYn59HURRUVUXXdTKZTCTAtm2Ojo585dwP6rx3Qa+vrzSbTdbX11lZWSEWi4UCLMvi5uaGSqWC53mh/67esa/qTNOkXC4DoGka2WyWVCoFgOu6tFotDMPAtu3QXISNA8tbRKjVaoEnPCwPYZZ1nnHP8+ww2Ed7P0RE7LjneX/7ff6ocES0pbiIfBWRP57n2aMAwywKGdsi8ltRlO//AFPkniYXwGRMAAAAAElFTkSuQmCC', 'udemy': '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', 'youtube': 'iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMNwAADDcBracSlQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKkSURBVEiJxZcxSBthFIC/918uGhxMsyptcGjoIgGHW9wSihQKGZrNthHsIC7S1TqWgkRwcZV2lKo0FouixaEuEQ4khIIdrClkEoIZgiae93fQgFgll5jqt93x3v++e3f/3TvhGgYHBx/UarUUEAMeA48A/3WxDagBf4A9EdmsVqsfd3d3j64GyeWDZDJpFAqFKWAC6G6haCPKIjKTzWbfA+4/Ev39/V2dnZ3LwNP/UPwqaycnJy9yuVwFQF2cVIFA4PMdCQAMBQKBL8lk0gAwACzLmtJav7kjgTp95XK5ViwWf0g0Gg36/f7fQLBRltYaEWkU5hkRKTmO06dM03ztRaAuEQ6H0Vq3RUJrHTIM46XR29v7jvNt2BClFEtLS0QiEfb39ymVSrfujIg4Cog0mxiPx1lYWGBycpKenh5c122cdANa64gCHra6QCKRYHl5mfHxcYLBII7jtLJMWAEdrUrUSaVSrK6uMjo6SigU4uzsrJn0DtU4xhs+n4+xsTFWVlYYHh6mq6vL821qm0Qd0zSZmJggk8kQi8XuR6LO1tYW+XzeUzd87S6ey+WYnZ0ln88jIijV+DrbJnF4eMj09DTb29u4rtvU+8MHVLnFDjk+PiadTrO+vs7p6WkrS1R9QAGPb8zLaK2Zm5tjcXGRSqXiqe03sO8D9pqVyGQyzM/PUywWMQzjNgIAv3xa600Ree4l2nEcRkZGODg4QCmFYRi3KQ6AiGzIwMBAt2EYB9znp9y27bLWesZjUtsELkjbtl2ur6osy/qqtX7W7io3ISIb2Wx2CHDrT5TrOE4SWLsjgW+O4yS4mLiv9ldZljWptX6Lx2mrSY6A9M7OzgeuG/kvE41Gg6ZpvhKROPCE85mj5Z8fEfnpuu5313U/2bZdvhr0F9Fo9phaoDu9AAAAAElFTkSuQmCC' } footer = '''<div align="right"> <p align="right"><b>''' + self.tr( 'Author: Leandro Franca', 'Autor: Leandro França' ) + '''</b></p> <div align="right"> <a target="_blank" rel="noopener noreferrer" href="https://www.udemy.com/user/leandro-luiz-silva-de-franca/"><img title="Udemy" src="data:image/png;base64,''' + dic_BW[ 'udemy'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/GEOCAPT/"><img title="Facebook" src="data:image/png;base64,''' + dic_BW[ 'face'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/channel/UCLrewDGciytcBG9r0OxTW2w"><img title="Youtube" src="data:image/png;base64,''' + dic_BW[ 'youtube'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.researchgate.net/profile/Leandro_Franca2"><img title="ResearchGate" src="data:image/png;base64,''' + dic_BW[ 'RG'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://github.com/LEOXINGU"><img title="GitHub" src="data:image/png;base64,''' + dic_BW[ 'github'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.linkedin.com/in/leandro-fran%C3%A7a-93093714b/"><img title="Linkedin" src="data:image/png;base64,''' + dic_BW[ 'linkedin'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="http://lattes.cnpq.br/8559852745183879"><img title="Lattes" src="data:image/png;base64,''' + dic_BW[ 'lattes'] + '''"></a> </div> </div>''' return self.tr(txt_en, txt_pt) + footer FOLDER = 'FOLDER' SUBFOLDER = 'SUBFOLDER' FORMAT = 'FORMAT' GEOMETRY = 'GEOMETRY' OUTPUT = 'OUTPUT' CRS = 'CRS' def initAlgorithm(self, config=None): # INPUT self.addParameter( QgsProcessingParameterFile( self.FOLDER, self.tr('Folder with raster files', 'Pasta com arquivos raster'), behavior=QgsProcessingParameterFile.Folder, defaultValue=None)) self.addParameter( QgsProcessingParameterBoolean(self.SUBFOLDER, self.tr('Check subfolders', 'Verificar sub-pastas'), defaultValue=False)) self.addParameter( QgsProcessingParameterString(self.FORMAT, self.tr('Format', 'Formato'), defaultValue='.tif')) self.addParameter( QgsProcessingParameterEnum(self.GEOMETRY, self.tr('Geometry', 'Geometria'), options=[ self.tr('Polygon', 'Polígono'), self.tr('Point', 'Ponto') ], defaultValue=0)) self.addParameter( QgsProcessingParameterCrs(self.CRS, self.tr('CRS', 'SRC'), 'ProjectCrs')) # OUTPUT self.addParameter( QgsProcessingParameterFeatureSink( self.OUTPUT, self.tr('Inventory Layer', 'Camada de Inventário'))) def processAlgorithm(self, parameters, context, feedback): pasta = self.parameterAsFile(parameters, self.FOLDER, context) if not pasta: raise QgsProcessingException( self.invalidSourceError(parameters, self.FOLDER)) subpasta = self.parameterAsBool(parameters, self.SUBFOLDER, context) formato = self.parameterAsString(parameters, self.FORMAT, context) geometria = self.parameterAsEnum(parameters, self.GEOMETRY, context) crs = self.parameterAsCrs(parameters, self.CRS, context) # OUTPUT GeomType = QgsWkbTypes.Point if geometria == 1 else QgsWkbTypes.Polygon Fields = QgsFields() itens = { self.tr('name', 'nome'): QVariant.String, self.tr('extension', 'extensão'): QVariant.String, self.tr('path', 'caminho'): QVariant.String, self.tr('resX'): QVariant.Double, self.tr('resY'): QVariant.Double, self.tr('n_cols'): QVariant.Int, self.tr('n_rows', 'n_lin'): QVariant.Int, self.tr('crs', 'src'): QVariant.String, self.tr('n_bands', 'n_bandas'): QVariant.Int, self.tr('dataType', 'tipoDado'): QVariant.String, } for item in itens: Fields.append(QgsField(item, itens[item])) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, Fields, GeomType, crs) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) # Listar Arquivos feedback.pushInfo( self.tr('Checking files in the folder...', 'Checando arquivos na pasta...')) lista = [] if subpasta: for root, dirs, files in os.walk(pasta, topdown=True): for name in files: if name[-1 * len(formato):] == formato: lista += [os.path.join(root, name)] else: for item in os.listdir(pasta): if item[-1 * len(formato):] == formato: lista += [os.path.join(pasta, item)] total = 100.0 / len(lista) if len(lista) > 0 else 0 # Obter dados dos arquivos listados feedback.pushInfo( self.tr('Creating raster files...', 'Criando inventário de arquivos raster...')) for current, file_path in enumerate(lista): image = gdal.Open(file_path) # https://gdal.org/python/ prj = image.GetProjection() # wkt ulx, xres, xskew, uly, yskew, yres = image.GetGeoTransform() GDT = image.GetRasterBand(1).DataType n_bands = image.RasterCount cols = image.RasterXSize # Number of columns rows = image.RasterYSize # Number of rows CRS = QgsCoordinateReferenceSystem(prj) # Create CRS image = None # Close image # Creating BBox coord = [[ QgsPointXY(ulx, uly), QgsPointXY(ulx + cols * xres, uly), QgsPointXY(ulx + cols * xres, uly + rows * yres), QgsPointXY(ulx, uly + rows * yres), QgsPointXY(ulx, uly) ]] geom = QgsGeometry.fromPolygonXY(coord) # CRS transformation coordinateTransformer = QgsCoordinateTransform() coordinateTransformer.setDestinationCrs(crs) coordinateTransformer.setSourceCrs(CRS) geom_transf = self.reprojectPoints(geom, coordinateTransformer) # Attributes path, file = os.path.split(file_path) name = os.path.splitext(file)[0] extension = os.path.splitext(file)[1] att = [ name, extension, path, abs(xres), abs(yres), cols, rows, CRS.description(), n_bands, gdal.GetDataTypeName(GDT) ] # Saving feature feat = QgsFeature() feat.setGeometry(geom_transf.centroid() ) if geometria == 1 else feat.setGeometry( geom_transf) # centroid or polygon feat.setAttributes(att) sink.addFeature(feat, QgsFeatureSink.FastInsert) if feedback.isCanceled(): break feedback.setProgress(int((current + 1) * total)) feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo('Leandro França - Eng Cart') return {self.OUTPUT: dest_id} def reprojectPoints(self, geom, xform): if geom.type() == 0: #Point if geom.isMultipart(): pnts = geom.asMultiPoint() newPnts = [] for pnt in pnts: newPnts += [xform.transform(pnt)] newGeom = QgsGeometry.fromMultiPointXY(newPnts) return newGeom else: pnt = geom.asPoint() newPnt = xform.transform(pnt) newGeom = QgsGeometry.fromPointXY(newPnt) return newGeom elif geom.type() == 1: #Line if geom.isMultipart(): linhas = geom.asMultiPolyline() newLines = [] for linha in linhas: newLine = [] for pnt in linha: newLine += [xform.transform(pnt)] newLines += [newLine] newGeom = QgsGeometry.fromMultiPolylineXY(newLines) return newGeom else: linha = geom.asPolyline() newLine = [] for pnt in linha: newLine += [xform.transform(pnt)] newGeom = QgsGeometry.fromPolylineXY(newLine) return newGeom elif geom.type() == 2: #Polygon if geom.isMultipart(): poligonos = geom.asMultiPolygon() newPolygons = [] for pol in poligonos: newPol = [] for anel in pol: newAnel = [] for pnt in anel: newAnel += [xform.transform(pnt)] newPol += [newAnel] newPolygons += [newPol] newGeom = QgsGeometry.fromMultiPolygonXY(newPolygons) return newGeom else: pol = geom.asPolygon() newPol = [] for anel in pol: newAnel = [] for pnt in anel: newAnel += [xform.transform(pnt)] newPol += [newAnel] newGeom = QgsGeometry.fromPolygonXY(newPol) return newGeom else: return None
class ExtendLines(QgsProcessingAlgorithm): LOC = QgsApplication.locale() def translate(self, string): return QCoreApplication.translate('Processing', string) def tr(self, *string): # Traduzir para o portugês: arg[0] - english (translate), arg[1] - português if self.LOC == 'pt': if len(string) == 2: return string[1] else: return self.translate(string[0]) else: return self.translate(string[0]) def createInstance(self): return ExtendLines() def name(self): return 'extendlines' def displayName(self): return self.tr('Extend lines', 'Estender linhas') def group(self): return self.tr('LF Vector', 'LF Vetor') def groupId(self): return 'lf_vector' def shortHelpString(self): txt_en = 'Extends lines at their <b>start</b> and/or <b>end</b> points.' txt_pt = 'Estende linhas nos seus pontos inicial e/ou final.' dic_BW = { 'face': 'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMwAADDMBUlqVhwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIUSURBVEiJvZa9quJAGIbfMfEYTUSUQAqLYOnehJobsBTlHLbRQtKKlY3lObegxRa7pRdg7y0saiuoKAErMZif2Squ2eTEOCfsC1Pk+3uYb2YyQwCg1+u9UUqHAKoAOCQrB8ASwPt0Ov1JdF3/bprmj4QhoXp5eXnjTdMcUEr/Bw+WZQ15Smn1q4UIIZBlGaIoghBys2+3W1yv19u367rfeAAc6ww5jkOz2USj0YAoigH/aDTCbrfzpfCUUrAC2+02NE2LjPm3NjNQkiTU6/WHsFAgi1RVRSqVCthd171BwmozA/P5fMA2n88xm81g2zYAwHGccCAL9H43elosFrhcLpE5zMCwHMdxImtRSp8DptNpZDIZAIAgCAG/IAi+42Ga5q29nkin06FxgZqmodvtxooFgPF4jPV67bM9NcNnW384HJI7h49kWRZOp9PXgOfzGfv9HgCQy+VQKBR8fsMwYFkWAOB4PMJ13UAN0mq1Yq/hfVytVoOu6z7/YDDAZrP5Wzzk6CR6LOLEJLqGcWrxYX2OW5wJmOQOjQX0ApOERgIrlQoTUJblgK1cLodeWZ4IIeDDngZx5P1T75XNZiFJUmQeTyl1wPAW/awrD7rlpDiOW3qL/cz4DBY1CCG/U4qifDw7O1YpivJBAGAymbwahjG0bbtKKeXjJJdKJaiq6rOtVqvAjU8IsTmOWxaLxfd+v//rD1H2cZ8dKhk8AAAAAElFTkSuQmCC', 'github': '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', 'instagram': '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', 'lattes': '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', 'linkedin': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6QAADOkBmiiHWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJRSURBVEiJ7ZU/aCJREMa/t7soa5LOoGihktZOQSxSWykBIYVaWZ6NVa6wSZ/WI5BGziJypA1CQBLsgkKKgBjFQkEtkouJ+AdxdeeKnHvurXdcXK84uK/amfl4v9m3s++xbrdrury8PGm324dEZMYGxRj7arPZvoRCoSPh/Pz8pFqtftgkYEnmTqeT6PV6xDscjs9EZPpLIADAy8uLS5jP52bGGACA4ziEw2H4/X5IkoSrqytcX1/rBhHRrrCcCAaDCAQCShyJRPD6+oq7uzvdMG458Hg8GoPX69UN0YDG47HGsCqnG5TP50FESjyZTFAoFDYCYvF4nBbDAAB7e3vw+XyQJAnFYhGPj4+6IUQE4eekJEm4vb0F8DaFC1mtVphMb3+BLMtotVogItjtdjgcDhiNRvT7fTw8PKzcbhXI5XIhlUqpOkkkEpjP5zg+PoYg/LCfnp5if38fbrdbteB0OsXFxQVubm5+DTIYDKoiYww8z4OIwPO8qhaLxbCzs6Pp3GAwIBqN4vn5Gff390qe0zj/UKsgywqFQqpY843eo1KphHK5DLPZjIODAxiNRqXmdDqxvb2N4XCoD1Sv13F2dqbEs9kM0WhU5bFYLApo7a1bTOZClUpF49na2lKe1wb1ej1VvGqklwdobdB79R/0j4FkWdYYiEh1dawrAcATgF0AaDabyOVyyuE5HA4xmUwAAJlMRjl2ZFlGo9FQLTQajZDNZiGKouKp1WqL8hNLJpPpwWCQ0N3ybySKYpqLxWJHjLFP399s03riOC4dCAQ+fgMeouMzfwx22gAAAABJRU5ErkJggg==', 'RG': 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAcCAYAAAB2+A+pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMfwAADH8BdgxfmQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM2SURBVEiJtZdLSytJFMd/1dXB+OiQRJEQBEnbPgISJGIQcePKjyBZzoP5AH6OuR9gFjPMznwC1650EbKSy00WPhJ8EMlDtG1M0p2axZCA1871cZM/NDRFnfqdqjrnVJUAODg4+E0IsQ8sA5LRyANKQogve3t7/4hcLvcH8NeIYL5SSv2uAftDHhSl1A/7CCH2dWBxWNBoNIppmgSDQarVKufn53ie59d1RQO0YUBjsRg7OztomkatVmNpaYnNzU2EEH7dNX0YUKUUpmlyd3dHPp9HKcXV1RXT09MIIXyXfihgKSWGYVCpVPoQ27axbXugjS/4HcHh29btdlFKsbq6SiwWA6BQKHB/f/82WEpJKpUiEAi8aA8EAiilaLVaNBoNrq+vabfbr+BCCG5vb3l8fCSTyaDr/ov6KrA8z6NcLtNqtUgkEszPz+M4Ds1mE9u2MQyDjY0Ndnd3mZmZ6ds4jkMoFAKg0Wjw8PCAEIJOp+ML9nWnZ5hIJJBSUiqV+gMIIbAsi3Q6zdbWFoeHh7iuS7lcZn19HcdxsG0by7Ko1+sD93lgcCml6Ha7SClftZ+dnbG4uIhhGMzOznJzc0OlUkHTNBYWFtB1nXq9zunp6aA8/lxUe57H09MThmEwPj7ed+ji4oLLy0uEEHieNyiHPw+WUjI5OYlS6lXE9krmj6DwyaplmiaGYVCtVqnX658Z4u0ZCyGIx+O0223GxsaYm5sjHo9Tq9U4OTn5FPRdYCkly8vLCCEIh8MopSgUCpTLZVzXHR3YdV2Ojo7wPI/t7W1isRjBYPCnoPDOPVZK4XlePz2SySThcHj04J4ajQbFYhEpJZlM5lWOjwwMUCwWaTabRCIR0un08MG9gt/778l1XfL5PJ1OB9M0WVlZGR54amoKy7IIBoPouo5lWYRCof7SNptN8vk83W6XVCrF2toaExMTHwKLXC734vCVUpJOp9F1/cW5rGkapVLpRcGIRqMkk0kikQiO43B8fMzz8/O7wd73Mx90EfArg0opNE178/LwnboaUPID+H2DnPkgFOCbppT68lGrn5VS6k8tm83+DfwKfOX/Z8ao5AFflVK/ZLPZf/8DudZq3wvXLmgAAAAASUVORK5CYII=', 'tweeter': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMQAADDEBLaRWDgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK5SURBVEiJpZU7T+NAFEZP4kAePBwZ8TA0EUIRKKIgQhSImnZ/wDYr7Q/barddbRu2QVAQhChAgBQqQClwFEIcx8IYfLdKNk5sJ4GRRh6PPN+Z+90749jZ2VnGsqyfwD6QEREARISocdRcT7dF5AD4lmi327+AL0GCn4QgIhkR+SIiPxIish8k3i/yQVCn7ydEJD0sgjDBMUCZxCg2hQmqqsri4iKKotBoNKhWq741vesSvULpdJrJyUkajcZQy7a2tlheXqa3FQoFzs/PmZubQ9M0Dg8Pu2vivQJLS0sUi0Wy2WykFfl8fgACkEql2N3dJZfLcXFxgaqq/0G9O04mk8RiMba3t8nlcqHRrK6uDkB628TEBDs7O5imORgRgGVZ3Y/z+Tx7e3ssLCz4QMlkkng8HglqNpscHBzw9vbmz1EHVK1WWVtb6wpNTU1RLBZ5f3/HMAzq9TqO40RCAGq1Gq7r+jboK4aZmRmurq7Y3Nz0LVQUBV3X0XV9KATAcZwBy7vlLSJomjbU/1Ha8/PzAMhXdQ8PD5+GABiGEQ1qt9tcXl5+CvL09MTLy8ugdf0T9/f32LbNxsYGs7OzY4Our68DD/oASEQoFApMT0+PDTFNk7u7u0BQPAhULpdxXXds0PHxMZ7nDUBCQa1Wi1KpRKVSwTTNkSAnJyfU6/XQWz4QJCI4jsPj4yOKogyFnJ6ecnt7G3nTd3OUSCSYn59HURRUVUXXdTKZTCTAtm2Ojo585dwP6rx3Qa+vrzSbTdbX11lZWSEWi4UCLMvi5uaGSqWC53mh/67esa/qTNOkXC4DoGka2WyWVCoFgOu6tFotDMPAtu3QXISNA8tbRKjVaoEnPCwPYZZ1nnHP8+ww2Ed7P0RE7LjneX/7ff6ocES0pbiIfBWRP57n2aMAwywKGdsi8ltRlO//AFPkniYXwGRMAAAAAElFTkSuQmCC', 'udemy': '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', 'youtube': 'iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMNwAADDcBracSlQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKkSURBVEiJxZcxSBthFIC/918uGhxMsyptcGjoIgGHW9wSihQKGZrNthHsIC7S1TqWgkRwcZV2lKo0FouixaEuEQ4khIIdrClkEoIZgiae93fQgFgll5jqt93x3v++e3f/3TvhGgYHBx/UarUUEAMeA48A/3WxDagBf4A9EdmsVqsfd3d3j64GyeWDZDJpFAqFKWAC6G6haCPKIjKTzWbfA+4/Ev39/V2dnZ3LwNP/UPwqaycnJy9yuVwFQF2cVIFA4PMdCQAMBQKBL8lk0gAwACzLmtJav7kjgTp95XK5ViwWf0g0Gg36/f7fQLBRltYaEWkU5hkRKTmO06dM03ztRaAuEQ6H0Vq3RUJrHTIM46XR29v7jvNt2BClFEtLS0QiEfb39ymVSrfujIg4Cog0mxiPx1lYWGBycpKenh5c122cdANa64gCHra6QCKRYHl5mfHxcYLBII7jtLJMWAEdrUrUSaVSrK6uMjo6SigU4uzsrJn0DtU4xhs+n4+xsTFWVlYYHh6mq6vL821qm0Qd0zSZmJggk8kQi8XuR6LO1tYW+XzeUzd87S6ey+WYnZ0ln88jIijV+DrbJnF4eMj09DTb29u4rtvU+8MHVLnFDjk+PiadTrO+vs7p6WkrS1R9QAGPb8zLaK2Zm5tjcXGRSqXiqe03sO8D9pqVyGQyzM/PUywWMQzjNgIAv3xa600Ree4l2nEcRkZGODg4QCmFYRi3KQ6AiGzIwMBAt2EYB9znp9y27bLWesZjUtsELkjbtl2ur6osy/qqtX7W7io3ISIb2Wx2CHDrT5TrOE4SWLsjgW+O4yS4mLiv9ldZljWptX6Lx2mrSY6A9M7OzgeuG/kvE41Gg6ZpvhKROPCE85mj5Z8fEfnpuu5313U/2bZdvhr0F9Fo9phaoDu9AAAAAElFTkSuQmCC' } image = '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' footer = '''<div> <div align="center"> <img src="data:image/jpg;base64,''' + image + ''' </div> <div align="right"> <p align="right"> <b>''' + self.tr( 'Author: Leandro Franca', 'Autor: Leandro França' ) + '''</b> </p> <a target="_blank" rel="noopener noreferrer" href="https://www.udemy.com/user/leandro-luiz-silva-de-franca/"><img title="Udemy" src="data:image/png;base64,''' + dic_BW[ 'udemy'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/GEOCAPT/"><img title="Facebook" src="data:image/png;base64,''' + dic_BW[ 'face'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/channel/UCLrewDGciytcBG9r0OxTW2w"><img title="Youtube" src="data:image/png;base64,''' + dic_BW[ 'youtube'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.researchgate.net/profile/Leandro_Franca2"><img title="ResearchGate" src="data:image/png;base64,''' + dic_BW[ 'RG'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://github.com/LEOXINGU"><img title="GitHub" src="data:image/png;base64,''' + dic_BW[ 'github'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.linkedin.com/in/leandro-fran%C3%A7a-93093714b/"><img title="Linkedin" src="data:image/png;base64,''' + dic_BW[ 'linkedin'] + '''"></a> <a target="_blank" rel="noopener noreferrer" href="http://lattes.cnpq.br/8559852745183879"><img title="Lattes" src="data:image/png;base64,''' + dic_BW[ 'lattes'] + '''"></a> </div> </div>''' return self.tr(txt_en, txt_pt) + footer LINES = 'LINES' TYPE = 'TYPE' DISTANCE = 'DISTANCE' OUTPUT = 'OUTPUT' def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterVectorLayer( self.LINES, self.tr('Line Layer', 'Camada de Linhas'), [QgsProcessing.TypeVectorLine])) tipo = [ self.tr('Start and End points', 'Pontos inicial e final'), self.tr('Only End Point', 'Apenas ponto final'), self.tr('Only Start Point', 'Apenas ponto inicial') ] self.addParameter( QgsProcessingParameterEnum(self.TYPE, self.tr('Attributes', 'Atributos'), options=tipo, defaultValue=0)) self.addParameter( QgsProcessingParameterNumber(self.DISTANCE, self.tr('Distance', 'Distância'), type=1, defaultValue=25.0)) self.addParameter( QgsProcessingParameterFeatureSink( self.OUTPUT, self.tr('Extended lines', 'Linhas estendidas'))) def processAlgorithm(self, parameters, context, feedback): linhas = self.parameterAsVectorLayer(parameters, self.LINES, context) if linhas is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.LINES)) tipo = self.parameterAsEnum(parameters, self.TYPE, context) Distancia = self.parameterAsDouble(parameters, self.DISTANCE, context) if Distancia is None or Distancia < 0: raise QgsProcessingException( self.tr('The input distance must be grater than 0!', 'A distância de entrada deve ser maior que 0!')) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, linhas.fields(), linhas.wkbType(), linhas.sourceCrs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) # Camada de entrada SRC = linhas.sourceCrs() fields = linhas.fields() extensao = linhas.sourceExtent() y_max = extensao.yMaximum() y_min = extensao.yMinimum() # Transformar distancia para graus, se o SRC for Geográfico if SRC.isGeographic(): EPSG = int(SRC.authid().split(':')[-1]) proj_crs = CRS.from_epsg(EPSG) a = proj_crs.ellipsoid.semi_major_metre f = 1 / proj_crs.ellipsoid.inverse_flattening e2 = f * (2 - f) N = a / np.sqrt(1 - e2 * (np.sin( (y_min + y_max) / 2))**2) # Raio de curvatura 1º vertical M = a * (1 - e2) / (1 - e2 * (np.sin((y_min + y_max) / 2))**2)**( 3 / 2.) # Raio de curvatura meridiana R = np.sqrt(M * N) # Raio médio de Gauss theta = Distancia / R Distancia = np.degrees(theta) # Radianos para graus # Varrer linhas Percent = 100.0 / linhas.featureCount() if linhas.featureCount( ) > 0 else 0 for index, feat in enumerate(linhas.getFeatures()): geom = feat.geometry() att = feat.attributes() if geom: if geom.isMultipart(): lines = geom.asMultiPolyline() for line in lines: P1 = line[0] P2 = line[1] Pn = line[-1] Pn_1 = line[-2] P_ini = QgsGeometry.fromPointXY(P1) P_fim = QgsGeometry.fromPointXY(Pn) if tipo == 0 or tipo == 2: vetor = array(P1) - array(P2) P = array(P1) + vetor / norm(vetor) * Distancia P1 = QgsPointXY(P[0], P[1]) if tipo == 0 or tipo == 1: vetor = array(Pn) - array(Pn_1) P = array(Pn) + vetor / norm(vetor) * Distancia Pn = QgsPointXY(P[0], P[1]) if tipo == 0: line = [P1] + line[1:-1] + [Pn] elif tipo == 1: line = line[0:-1] + [Pn] elif tipo == 2: line = [P1] + line[1:] new_geom = QgsGeometry.fromPolylineXY(line) feature = QgsFeature(fields) feature.setAttributes(att) feature.setGeometry(new_geom) sink.addFeature(feature, QgsFeatureSink.FastInsert) else: line = geom.asPolyline() P1 = line[0] P2 = line[1] Pn = line[-1] Pn_1 = line[-2] P_ini = QgsGeometry.fromPointXY(P1) P_fim = QgsGeometry.fromPointXY(Pn) if tipo == 0 or tipo == 2: vetor = array(P1) - array(P2) P = array(P1) + vetor / norm(vetor) * Distancia P1 = QgsPointXY(P[0], P[1]) if tipo == 0 or tipo == 1: vetor = array(Pn) - array(Pn_1) P = array(Pn) + vetor / norm(vetor) * Distancia Pn = QgsPointXY(P[0], P[1]) if tipo == 0: line = [P1] + line[1:-1] + [Pn] elif tipo == 1: line = line[0:-1] + [Pn] elif tipo == 2: line = [P1] + line[1:] new_geom = QgsGeometry.fromPolylineXY(line) feature = QgsFeature(fields) feature.setAttributes(att) feature.setGeometry(new_geom) sink.addFeature(feature, QgsFeatureSink.FastInsert) if feedback.isCanceled(): break feedback.setProgress(int((index + 1) * Percent)) feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo( self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart')) return {self.OUTPUT: dest_id}