├── sql
└── README.md
├── python
├── pypgis
│ ├── database.ini
│ ├── config.py
│ └── connect.py
├── paralelas
│ ├── paracatu.sqlite
│ ├── README.md
│ └── linhas_paralelas.py
├── shp2spatialite
│ ├── test.sqlite
│ ├── territorios.dbf
│ ├── territorios.shp
│ ├── territorios.shx
│ ├── territorios.prj
│ └── shp2spatialite.py
├── funcoes_qgis
│ ├── data_exemplo.dbf
│ ├── raiocurv.py
│ ├── wrap_delimiter.py
│ ├── verifica_valor.py
│ ├── polygon_sphericity.py
│ ├── vertices_to_html.py
│ ├── padroniza_data.py
│ ├── plot_tree.py
│ └── README.md
├── donwload_landsat_google
│ ├── requirements.txt
│ ├── download_loop.py
│ └── README.md
├── csv2postgis
│ ├── __pycache__
│ │ ├── config.cpython-35.pyc
│ │ └── config.cpython-36.pyc
│ ├── arquivo.csv
│ ├── database.ini
│ ├── config.py
│ ├── csv2postgis.py
│ └── README.md
├── cria_prj
│ ├── README.md
│ └── cria_prj.py
├── scripts
│ ├── salva_camadas
│ │ ├── README.md
│ │ └── salva_camadas_kml.py
│ ├── sigef_services
│ │ ├── README.md
│ │ └── add_servicos_sigef.py
│ ├── reorder_vertices
│ │ ├── README.md
│ │ └── reorder_vertices.py
│ ├── save_selected
│ │ ├── README.md
│ │ └── save_selected.py
│ ├── vector_layers_attribute_txt
│ │ └── export_vector_layers_attibute.py
│ ├── generate_label
│ │ ├── README.md
│ │ └── generate_label.py
│ ├── README.md
│ └── load_functions
│ │ └── startup.py
├── processing_scripts
│ ├── README.md
│ └── generate_label
│ │ ├── README.md
│ │ └── generate_label.py
├── select_unique
│ ├── README.md
│ └── select_unique.py
├── gridpoints
│ ├── gridpoints.md
│ └── gridpoints.py
├── ogr_shp2kml
│ ├── README.md
│ └── ogr_shp2kml.py
├── README.md
├── change_encode
│ ├── README.md
│ └── change_encode.py
├── reproj_recursive
│ ├── README.md
│ └── reproj_recursive.py
└── gdal_recursive
│ ├── README.md
│ └── gdal_recursive.py
├── docs
├── README.md
└── Python_postgis.md
├── shell
├── rm_amazon.sh
├── shp2pgsql.md
├── raio_curv.awk
├── pgis2geopkg.sh
├── pgis2shp.sh
├── proj4_geo2utm.sh
├── rotac_nuvemptos.sh
├── README.md
├── csv2shp_ogr_point.sh
├── cria_dtm_gdal.sh
└── gdal_tranlate.md
└── README.md
/sql/README.md:
--------------------------------------------------------------------------------
1 | # qgis-tips-tricks
2 | Dicas e truques a serem usadas no qgis, utilizando SQL.
3 | Use a vontade...
4 |
--------------------------------------------------------------------------------
/python/pypgis/database.ini:
--------------------------------------------------------------------------------
1 | [postgresql]
2 | host=localhost
3 | database=dbteste
4 | user=jmenezes
5 | password=SECRETA
6 |
--------------------------------------------------------------------------------
/python/paralelas/paracatu.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/paralelas/paracatu.sqlite
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - DOCS
2 |
3 | Documentações mais elaboradas podem ser colocadas aqui.
4 | Use a vontade...
5 |
--------------------------------------------------------------------------------
/python/shp2spatialite/test.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/shp2spatialite/test.sqlite
--------------------------------------------------------------------------------
/python/funcoes_qgis/data_exemplo.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/funcoes_qgis/data_exemplo.dbf
--------------------------------------------------------------------------------
/python/shp2spatialite/territorios.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/shp2spatialite/territorios.dbf
--------------------------------------------------------------------------------
/python/shp2spatialite/territorios.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/shp2spatialite/territorios.shp
--------------------------------------------------------------------------------
/python/shp2spatialite/territorios.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/shp2spatialite/territorios.shx
--------------------------------------------------------------------------------
/python/donwload_landsat_google/requirements.txt:
--------------------------------------------------------------------------------
1 | Landsat578
2 | cython
3 | dask
4 | toolz
5 | cloudpickle
6 | future
7 | fastparquet
8 |
9 |
--------------------------------------------------------------------------------
/python/csv2postgis/__pycache__/config.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/csv2postgis/__pycache__/config.cpython-35.pyc
--------------------------------------------------------------------------------
/python/csv2postgis/__pycache__/config.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kylefelipe/qgis-tips-tricks/HEAD/python/csv2postgis/__pycache__/config.cpython-36.pyc
--------------------------------------------------------------------------------
/python/shp2spatialite/territorios.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/python/csv2postgis/arquivo.csv:
--------------------------------------------------------------------------------
1 | municipio;coluna_1;coluna_2
2 | 3117504;aaaaaaaa;11111111
3 | 3118106;bbbbbbbb;22222222
4 | 3140852;cccccccc;33333333
5 | 3135050;dddddddd;44444444
6 | 3106002;eeeeeeee;55555555
7 | 3134608;ffffffff;66666666
--------------------------------------------------------------------------------
/python/funcoes_qgis/raiocurv.py:
--------------------------------------------------------------------------------
1 | from math import pi, sqrt
2 | def raiocurv(a, f, lat):
3 | """a = semi-eixo maior
4 | f = achatamento do elipsoide
5 | lat = latitude"""
6 |
7 |
8 | if f > 1:
9 | f=1/f
10 |
11 | 'arcotangente2(0, -1)'
12 |
--------------------------------------------------------------------------------
/python/cria_prj/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - cria_prj
2 | __PYTHON__
3 | Cria o arquivo *prj quando ausente de um conjunto shapefile;
4 |
5 | A entrada: consiste no numero inteiro repesentando o EPSG
6 |
7 | A saida: um arquivo proj4.prj que devera ser renomeado para ser carregado no QGIS.
8 |
9 |
--------------------------------------------------------------------------------
/shell/rm_amazon.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # remove Amazon /www.lifewire.com/remove-amazon-application-from-ubuntu-4134329
3 | sudo rm /usr/share/applications/ubuntu-amazon-default.desktop
4 | sudo rm /usr/share/unity-webapps/userscripts/unity-webapps-amazon/Amazon.user.js
5 | sudo rm /usr/share/unity-webapps/userscripts/unity-webapps-amazon/manifest.json
6 | exit 0
7 |
--------------------------------------------------------------------------------
/python/scripts/salva_camadas/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - select_unique
2 | __Python__: 2.7
3 |
4 | This script saves all vectors layers form a QGIS project to a kml file in the same folder.
5 |
6 | USAGE:
7 | Open QGIS Python Terminal (Ctrl+Alt+P)
8 | Click "Show editor"
9 | Paste the code there or open the cript
10 | Click *Run Script*
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/python/processing_scripts/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - PROCESSING
2 |
3 | Scripts que feitos para serem utilizados através da caixa de ferramentas do processing do [QGIS](www.qgis.org)
4 |
5 | Quando adicionados ao [QGIS](www.qgis.org) os scriptis ficarão em `Scripts > Kyle scripts`
6 |
7 | * [generate_label](./generate_label/): Script para gerar uma coluna em uma camada de polígono ordenada pela área.
8 |
--------------------------------------------------------------------------------
/python/csv2postgis/database.ini:
--------------------------------------------------------------------------------
1 | [postgresql]
2 | host=
3 | port=5432
4 | database=shapes_basicos
5 | user=postgres
6 | password=
7 |
8 | [file_csv]
9 | path=/home/x12239181/qgis-tips-tricks/python/postgis/arquivo.csv
10 | delimiter=;
11 | key=municipio
12 |
13 | [table_csv]
14 | schema=public
15 | table=teste_csv
16 | key=municipio
17 |
18 | [join_table]
19 | schema=public
20 | table="Limites Municipais"
21 | key=geocodigo
22 | geometry=geom
23 |
--------------------------------------------------------------------------------
/python/select_unique/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - select_unique
2 | __Python__: 2.7
3 |
4 | This script selects vectors in a layer that that have unique values on a field.
5 |
6 | USAGE:
7 |
8 | Select a layer on QGIS Layer panel...
9 | Go to Plugins > Python Console
10 | Click "Open Script" and navigate to script folder.
11 | Change "comarca" to a field that you want to search for unique values. Keep it betwen " ".
12 | Click "RUN"...
13 |
14 |
15 |
--------------------------------------------------------------------------------
/python/scripts/sigef_services/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - add_servicos_sigef
2 |
3 | __Qgis__: >3.34
4 |
5 | Este script adiciona os geoserviços WMS ou WFS do SIGEF no QGIS.
6 |
7 | ## USAGE:
8 |
9 | Abra o Terminal Python no QGIS (Ctrl+Alt+P)
10 | Clique em "Mostrar editor"
11 | Copie o código do arquivo `add_servicos_sigef.py` e cole no editor
12 | Clique em *Run Script*
13 |
14 | Na primeira tela, selecione o estado, e na segunda selecione o serviço desejado.
15 |
--------------------------------------------------------------------------------
/python/select_unique/select_unique.py:
--------------------------------------------------------------------------------
1 | # Python Version 2.7
2 | # Author: Kyle Felipe
3 | # e-mail: kylefelipe@gmail.com
4 | # Date: 2018/05/12
5 |
6 | col_name = "COMARCA"
7 | layer = iface.activeLayer()
8 | iter = layer.getFeatures()
9 | at_data = {}
10 | unique_id = []
11 | for feature in iter:
12 | at_data[feature.id()]=feature[col_name]
13 | for i in at_data.keys():
14 | if at_data.values().count(at_data[i]) ==1:
15 | uniqueid.append(i)
16 |
17 | layer.setSelectedFeatures(uniqueid)
18 |
--------------------------------------------------------------------------------
/python/gridpoints/gridpoints.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - gridpoints
2 | __PYTHON__
3 | O script surgiu de uma necessidade de um colega no grupo [QGIS Brasil](www.qgisbrasil.org) no [Google Groups] (https://groups.google.com/forum/#!forum/qgisbrasil) que precisava gerar um grid de pontos UTM.
4 |
5 | A entrada: consiste nas coordenadas do canto superior esquerdo do grid, o numero de colunas e de linhas desejadas e o espacamento da malha.
6 |
7 | A saida: um arquivo CSV que pode ser carregado no QGIS.
8 |
9 |
10 |
--------------------------------------------------------------------------------
/python/paralelas/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - paralelas
2 | __PYTHON__
3 | O script surgiu de uma necessidade de um colega no grupo [QGIS Brasil](www.qgisbrasil.org) no [Google Groups] (https://groups.google.com/forum/#!forum/qgisbrasil) que precisava gerar linhas de plantio paralelas.
4 |
5 | É necessário um banco de dados SPATIALITE contendo a linha mestra que irá originar as paralelas.
6 | O exemplo usado no código é o BD 'Paracatu'.
7 | A tabela contendo a linha (LINESTRING) mestra de exemplo é a 'paracatu'.
8 |
9 |
--------------------------------------------------------------------------------
/python/scripts/reorder_vertices/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - reorder_vertices
2 | _QGIS VERSION:_ 3.xx.xx
3 |
4 | Esse script gera uma nova camada de pontos com os vértices de um polígono (Perímetro), reordenando a partir de um vértice escolhido como primeiro ponto e gera uma nomenclatura para esse vérice também.
5 |
6 | __NOTE:__ É necessário que haja uma camada ativa no painel de camadas e um polígono selecionado para funcionar.
7 |
8 | USAGE:
9 |
10 | Abra esse script no console python do [Qgis](www.qgis.org) e com a camada ativa e o polígono que deseja trabalhar selecionado rode o script.
11 |
--------------------------------------------------------------------------------
/python/pypgis/config.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from configparser import ConfigParser
3 |
4 |
5 | def config(filename='database.ini', section='postgresql'):
6 | # create a parser
7 | parser = ConfigParser()
8 | # read config file
9 | parser.read(filename)
10 |
11 | # get section, default to postgresql
12 | db = {}
13 | if parser.has_section(section):
14 | params = parser.items(section)
15 | for param in params:
16 | db[param[0]] = param[1]
17 | else:
18 | raise Exception('Section {0} not found in the {1} file'.format(section, filename))
19 |
20 | return db
21 |
--------------------------------------------------------------------------------
/shell/shp2pgsql.md:
--------------------------------------------------------------------------------
1 | # Comandos bash para importar varios arquivos vetoriais ao PortGIS.
2 | ### Atenção:
3 | #### comandos meramente ilustrativos. Vários parâmetros dos comando usados [shp2pgsql](https://postgis.net/docs/using_postgis_dbmanagement.html#shp2pgsql_usage) foram ignorados!
4 | ```
5 | for a in *.shp; do echo "Convertentado $a"; shp2pgsql $a schema.table > ${a%.*}.sql; done
6 | # Depois, para cada .SQL:
7 | for b in *.sql; do psql -d iis -f $b; done
8 | ```
9 |
10 | ### Alguns comentários
11 |
12 | * `${a%.*}` remove a extenção .shp do nome;
13 | * O processo aqui apresentados podem ser executados de forma seguida usando pipe `|`;
14 |
--------------------------------------------------------------------------------
/python/scripts/salva_camadas/salva_camadas_kml.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Author: Kyle Felipe Vieira Roberto
3 | # E-mail: kylefelipe@gmail.com
4 | # Date: 2018/05/22
5 |
6 | from os import sep
7 | layers = iface.legendInterface().layers()
8 |
9 | for layer in layers:
10 |
11 | caminho = str(layer.source()).split(sep)[:-1]
12 | arquivo = layer.name()+"_bkp"
13 | saida = sep.join(caminho)+sep+arquivo
14 | layerType = layer.type()
15 | if layerType == QgsMapLayer.VectorLayer:
16 | QgsVectorFileWriter.writeAsVectorFormat(layer, r"{saida}".format(saida=saida), "utf-8", None, "ESRI Shapefile")
17 | print r"{saida}".format(saida=arquivo)
18 |
19 |
--------------------------------------------------------------------------------
/python/csv2postgis/config.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | # -*- coding: utf-8 -*-
3 | from configparser import ConfigParser
4 |
5 |
6 | def config(filename='', section=''):
7 | """ This parser takes settings from a file .ini"""
8 | # create a parser
9 | parser = ConfigParser()
10 | # read config file
11 | parser.read(filename)
12 |
13 | # get section, default to postgresql
14 | db = {}
15 | if parser.has_section(section):
16 | params = parser.items(section)
17 | for param in params:
18 | db[param[0]] = param[1]
19 | else:
20 | raise Exception('Section {0} not found in the {1} file'.format(section, filename))
21 |
22 | return db
23 |
--------------------------------------------------------------------------------
/python/scripts/save_selected/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - save_selected
2 | _QGIS VERSION:_ 2.18 (Not tested with new version)
3 |
4 | This script makes a selection by using an qgis expression in all vectors layers within the QGIS project and then saves the selection to a shp file with the same name, plus "\_Dado_Filtrado", within the same layer folder.
5 | The new files will be added to the project within a group called "DADOS_FILTRADOS".
6 | __NOTE:__ All layers must have the same column used in the expression
7 |
8 | USAGE:
9 | exp > Qgis expression, you can make one using qgis field calculator and place it inside tree quotes (""" """)
10 | Ex: """ "field_3" = 12.2253 or $id = 3 """
11 |
--------------------------------------------------------------------------------
/python/scripts/vector_layers_attribute_txt/export_vector_layers_attibute.py:
--------------------------------------------------------------------------------
1 | """ Export all vectors layers attributes to a txt.
2 | Qgis Version: 2.18
3 | """
4 | import json
5 | campos = {}
6 | file = "C:\Temp\campos.txt" # file path
7 | for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
8 | if type(lyr) == QgsVectorLayer:
9 | fs = []
10 | for f in lyr.pendingFields():
11 | fs.append((f.name().encode('utf-8'), f.typeName().encode('utf-8')))
12 | campos[lyr.name().encode('utf-8')] = fs
13 |
14 | base = json.dumps(campos, indent=4, sort_keys=False, ensure_ascii=False, encoding="utf-8")
15 | #print base
16 | with open(file, 'w') as f:
17 | f.write(base)
18 | print "Arquivo Salvo!"
19 |
--------------------------------------------------------------------------------
/python/funcoes_qgis/wrap_delimiter.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from qgis.core import *
3 | from qgis.gui import *
4 |
5 | @qgsfunction(args='auto', group='String')
6 | def wrap_delimiter(text, delimiter, feature, parent):
7 | """
Returns a string wrapped to a delimiter
8 | Syntax
wrap_delimiter(string, delimiter)
9 | Arguments
10 | string = string to be wrapped
11 | delimiter = the delimiter string to wrap to a new line
12 | Example
wrap-delimiter('don't panic, it will be wrapped', ',')
13 | Result
14 | don't panic
15 | it will be wrapped
16 | """
17 | t = str(text).replace(delimiter+' ', delimiter)
18 | return str(t).replace(delimiter, "\n")
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks
2 |
3 | Dicas e truques a serem usadas no qgis e até mesmo em outros softwares, utilizando SQL, python, shell etc...
4 | A intenção é divulgar e aprofundar ainda mais o uso de opções livres para geoprocessamento, e não ficar presos à licenças.
5 |
6 | ## Diretórios
7 |
8 | * [DOCS](./docs): Documentação mais elaborada de algumas soluções disponibilizadas no repositório.
9 | * [python](./python) : Códigos feitos em python, como funções para serem usadas no QGIS, manipulação de banco de dados etc.
10 | * [shell](./shell): Dicas utilizando comandos via SHELL.
11 | * [sql](./sql): Códigos utilizando SQL em diversos Bancos de Dados Geográficos, como Spatialite, POSTGIS etc.
12 |
13 | Usem a vontade...
14 | Por favor, reportem "bugs" ou sugestoes, participem com "issues".
15 |
--------------------------------------------------------------------------------
/python/scripts/generate_label/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - generate_label
2 | _QGIS VERSION:_ 3.xx.xx
3 |
4 | Esse script gera uma nova camada virtual com a nova coluna com o rótulo da feição, ordenada pela área da geometria
5 |
6 | __NOTE:__ É necessário que haja uma camada ativa no painel de camadas para funcionar.
7 |
8 | USAGE:
9 |
10 | Abra esse script no console python do [Qgis](www.qgis.org) e com a camada ativa rode o script.
11 |
12 | ## Docs
13 |
14 | Variáveis que podem ser editadas no script
15 |
16 | * `virtual_layer_name` = Nome da camada virtual a ser gerada
17 | * `new_column` = Nome do campo novo
18 | * `prefix` = prefixo do campo novo - esta linha nao pode ser removida (Ex: A - 1, A - 2)
19 | * `sufix` = Sufixo - esta linha nao pode ser removida (Ex: 1 - A, 2 - A)
20 | * `dest_EPSG` = EPSG no qual deseja fazer o calculo de área (Ex: 31983)
21 |
--------------------------------------------------------------------------------
/shell/raio_curv.awk:
--------------------------------------------------------------------------------
1 | # $ GPL2 by yjmenezes at gmail dot com ver 1.0 2013-12-09 $
2 | # semi_eixo, achatamento, latitude graus decimais com sinal algebrico
3 | # calcula os raios de curvatura de secao meridiana (m) e primeiro vertical (v )
4 | awk 'function raio_curv(a_elip,f,lat_ddeg) {
5 | if ( f > 1.0) { f = 1.0 / f };
6 | lat = atan2(0, -1) * lat_ddeg
7 | s2 = sin(lat) * sin(lat);
8 | e2 = f * ( 2.0 - f);
9 | v = 1.0 - e2 * s2;
10 | m = ((1.0 - e2) * a_elip) / exp(1.5 * log(v));
11 | v = a_elip / sqrt(v);
12 | printf "%.2f ", sqrt(m * v);
13 | } { raio_curv($1,$2,$3); printf("\n"); }'
14 | # chamada da funcao lendo a entrada padrao e processando para saida padrao
15 | # echo "6378137.0 298.257223563 -31.767" | ./raio_curv.awk
16 | # echo "6378137.0 298.257223563 -31.767" | ./raio_curv.awk | awk '{ print "arco_1km_ddeg=", 1000 / $1 * 180 / atan2(0, -1) }'
17 |
--------------------------------------------------------------------------------
/python/cria_prj/cria_prj.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 | # Author: Julio Menezes cartognu.org#
4 | # ver 1.0 python 2.7.x , 2018-08-01, GNU/Linux Debian stretch 9.5
5 | import sys
6 | from osgeo import ogr, osr
7 | #
8 | def uso():
9 | sys.stderr.write ('Digite apenas numeros do EPSG\n')
10 | sys.stderr.write ('''
11 | exemplo de uso:
12 | python3 cria_prj.py 31985
13 | python cria_prj.py 31985
14 | posteriormente copie o proj4.prj com o nome do seu conjundo shapefile.
15 | ''')
16 | sys.exit(1)
17 |
18 | if __name__ == '__main__':
19 | if len(sys.argv) < 2:
20 | uso()
21 | spatialRef = osr.SpatialReference()
22 | spatialRef.ImportFromEPSG(int(sys.argv[1]))
23 | spatialRef.MorphToESRI()
24 | file = open('proj4.prj', 'w')
25 | file.write(spatialRef.ExportToWkt())
26 | file.close()
27 | sys.exit(0)
28 |
--------------------------------------------------------------------------------
/python/donwload_landsat_google/download_loop.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """Baixar imagem landsat 578"""
3 |
4 | from landsat.google_download import GoogleDownload
5 |
6 | path_row = [('218', '72'), ('218', '73'), ('218', '74'), ('218', '75')]
7 | data_inicial = '2017-01-01'
8 | data_final = '2017-02-02'
9 | cloud = 10
10 | image_folder = "/exercicios/baixando_imagem"
11 | satellite_n = 8
12 |
13 |
14 | def download_image(start_date, end_date, sat, img_path, img_row, max_cloud,
15 | folder):
16 | """Baixar a imagem do repo do google."""
17 | g = GoogleDownload(start=start_date, end=end_date, satellite=sat,
18 | path=img_path, row=img_row, output_path=folder,
19 | max_cloud_percent=float(max_cloud))
20 | g.download()
21 |
22 |
23 | for i in path_row:
24 | download_image(data_inicial, data_final, satellite_n, i[0], i[1], cloud)
25 |
--------------------------------------------------------------------------------
/shell/pgis2geopkg.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # GPL2 yjmenezes at gmail.com ver 1.0 2018-03-25
3 | # export PostGIS tables to OGC standard Geopackage using ogr2org
4 | #TODO fix Incorrectly quoted string literal message.
5 | if [ $# -lt 4 ]; then
6 | echo $(basename $0) "dbname username userpass out.gpkg"
7 | exit 1
8 | fi
9 | DB=$1
10 | OWN=$2
11 | PAS=$3
12 | PKG=$(basename $4 .gpkg)
13 | OUT=/tmp/pgout
14 | mkdir -p $OUT
15 | rm $OUT/*
16 | cd $OUT
17 | psql $DB -U $OWN -w -c "SELECT table_name FROM information_schema.tables
18 | WHERE table_schema='public' AND table_type='BASE TABLE';" | \
19 | awk 'NR > 2 { print $0 }' | grep -v -e \( -e ^$ -e spatial | \
20 | while read tbname; do
21 | echo "packing" $tbname 1>&2
22 | ogr2ogr -f "GPKG" $OUT/$PKG".gpkg" -update -append PG:"host=localhost user=$OWN dbname=$DB password=$PAS" $tbname
23 | done
24 | echo "please check" $OUT
25 | ls $OUT/* 1>&2
26 | exit 0
27 |
--------------------------------------------------------------------------------
/python/funcoes_qgis/verifica_valor.py:
--------------------------------------------------------------------------------
1 | @qgsfunction(args=3, group='Lista')
2 | def verifica_valor(values, feature, parent):
3 | """Retorna verdadeiro se um valor encontra-se dentro da lista, caso contrario, falso.
4 | Syntax
verifica_valor(lista, separador, pesquisa)
5 | Argument
LISTA = coluna onde encontra-se a lista de valores (Exemplo: "campo").
6 | SEPARADOR = simbolo do separador da lista(Exemplo: ',').
7 | PESQUISA = Valor procurado dentro da coluna.
8 | Example
verifica_valor("campo", ',',5)-> "5, 4, 6, 1" -> 5 -> TRUE
9 | """
10 |
11 | str_lista, separador, pesquisa = values[0], values[1], values[2]
12 | return str(pesquisa) in str_lista.replace(" ", "").split(separador)
13 |
--------------------------------------------------------------------------------
/shell/pgis2shp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # GPL2 yjmenezes at gmail.com ver 1.0 2018-03-25
3 | # export PostGIS tables to shapefile
4 | # tablenames must have 10 characters, max due SHP limitations;
5 | # to be used at server side host=localhost
6 | if [ $# -lt 3 ]; then
7 | echo $(basename $0) "dbname username userpass"
8 | exit 1
9 | fi
10 | DB=$1
11 | OWN=$2
12 | PAS=$3
13 | OUT=/tmp/pgout
14 | mkdir -p $OUT
15 | rm $OUT/*
16 | cd $OUT
17 | psql $1 -U $2 -w -c "SELECT table_name FROM information_schema.tables
18 | WHERE table_schema='public' AND table_type='BASE TABLE';" | \
19 | awk 'NR > 2 { print $0 }' | grep -v -e \( -e ^$ -e spatial | \
20 | while read tabname; do
21 | echo "processing" $tabname 1>&2
22 | pgsql2shp -u $OWN -P $PAS -f $OUT/$tabname $DB $tabname
23 | done
24 | echo "please check" $OUT
25 | ls $OUT/*shp 1>&2
26 | exit 0
27 | #----------------------------------------------------------------------------
28 |
--------------------------------------------------------------------------------
/python/donwload_landsat_google/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - PYTHON - change_encode
2 |
3 | ### Autor: Kyle Felipe
4 | ### Data: 05/10/2018
5 |
6 | Faz download das imagens LANDSAT 5, 7 e 8 do repositório do Google
7 |
8 | Pode ser utilizado no _Python 2_ ou superior, e é necessária a instalação dos pacotes listados no requirements.txt.
9 | pip install -r requirements.txt
10 |
11 | ## Modo de uso
12 |
13 | path_row = Uma lista com o path (orbita) e o Row (ponto) das images que desejam baixar no seguinte formato:
14 | [(path, row), ...]
15 | data_inicial = Iincio do periodo que deseja fazer o download, no formato AAAA-MM-DD.
16 | data_final = Final do periodo que deseja fazer o download, no formato AAAA-MM-DD.
17 | cloud = Quantidade do percentual maximo de núvem desejado em cada imagem.
18 | image_folder = local onde as imagens serão baixadas, ente "".
19 | satellite_n = Número do satélite LANDSAT que deseja as imagens. EX: 8.
20 |
--------------------------------------------------------------------------------
/python/ogr_shp2kml/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - PYTHON - ogr_shp2kml
2 |
3 | ### Autor: Kyle Felipe
4 | ### Data: 22/05/2018
5 |
6 | O script surgiu de uma necessidade de um colega do grupo [#ThinkFreeQgis](https://t.me/thinkfreeqgis) de salvar em KML arquivos shapefile dentro de um de [ogr2ogr](http://www.gdal.org/ogr2ogr.html) nos arquivos que estiverem dentro de pastas e subpastas, utilizando __Python__.
7 |
8 | Como exemplo, o script procura por um aquivo .shp dentro das pastas e o muda encoding para UTF-8
9 |
10 | Pode ser utilizado no _Python 2_ , e é necessária a instalação do pacote osgeo.
11 |
12 | ## Modo de uso
13 |
14 | python2 ogr_shp2kml.py <"endereço_da_pasta">
15 | <"endereço_da_pasta"> o endereço absoluto da pasta que deseja rodar a transformação, sempre deve ser informada entre aspas duplas "" sem a barra no final.
16 |
17 | * Exemplo: > python change_encode.py "UTF-8" "/home/temp"
18 |
19 | Os códigos podem ser alterados conforme a necessidade de utilização.
20 |
--------------------------------------------------------------------------------
/python/funcoes_qgis/polygon_sphericity.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from math import sqrt, pi
3 | @qgsfunction(args=2, group='Lista')
4 | def polygon_sphericity(values, feature, parent):
5 | """ calcula o grau de esfericidade do poligono.
6 | Quanto mais proximo de 1, mais circular o vetor é, quando mais proximo de 0, mais alongada.
7 | AS MEDIDAS DEVEM ESTAR NA MESMA UNIDADE
8 | Syntax
relate_area_perimeter(AREA, perimeter)
9 | Argument
AREA = coluna ou funçao referente a area do poligono (Exemplo: $area ).
10 | PERIMETER = coluna ou funçao referente ao perimetro do poligono (Exemplo: $perimeter).
11 | Example
relate_area_perimeter("$area, $perimeter)-> 0.607763480072298
12 | """
13 | constant = 1/(4*pi)
14 | area, perimeter= values[0], values[1]
15 | return sqrt(area/(constant*(perimeter**2)))
16 |
--------------------------------------------------------------------------------
/python/funcoes_qgis/vertices_to_html.py:
--------------------------------------------------------------------------------
1 | # Created At 2021-09-21
2 | # By Kyle Felipe At gmail.com
3 | # Font: https://inteligenciageograficaparatodos.blogspot.com/2020/10/funcoes-customizadas-lista-de-vertices.html
4 |
5 |
6 | from qgis.core import *
7 | from qgis.gui import *
8 |
9 | @qgsfunction(args='auto', group='Custom', referenced_columns=[], usesgeometry=True)
10 | def vetices_to_html(feat_geom,feature, parent):
11 | """
12 | Generates an html table with vertices from a given geometry
13 | Example usage:
14 |
15 | - vetices_to_html(geometry)
16 |
17 | """
18 | list_vertices = [' | Vértice | X | Y |
']
19 | vertices = feat_geom.vertices()
20 | for id, vertice in enumerate(vertices):
21 | list_vertices.append ((f' | {id} | {vertice.x()} | {vertice.y ()} |
' ))
22 | list_vertices.append('
')
23 | return '\n'.join(list_vertices)
24 |
--------------------------------------------------------------------------------
/shell/proj4_geo2utm.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # GPL2 by yjmenezes at gmail dot com ver 1.0 $ 2013-06-26
3 | # exemplo de uso do proj4, entrada wgs84 lat lon graus decimais
4 | proj +proj=utm +lon_0=51w +south +ellps=WGS84 -f "%.3f" -r << EOF
5 | -25.377403802778 -49.308814219444 917.219 bueiro1
6 | -25.3778093722 -49.30913235 919.430 prego1
7 | EOF
8 | # rearranjando a entrada para o proj4 com AWK
9 | cat << EOF | awk '{ print $3, $2, $4, $1 }' | \
10 | proj +proj=utm +zone=22 +south +ellps=WGS84 -f "%.3f"
11 | bueiro2 -25.377403802778 -49.308814219444 917.219
12 | prego2 -25.3778093722 -49.30913235 919.430
13 | EOF
14 | # +north
15 | proj +proj=utm +lon_0=51w +north +ellps=WGS84 -f "%.3f" -r << EOF
16 | 25.377403802778 -49.308814219444 917.219 bueiro3
17 | 25.3778093722 -49.30913235 919.430 prego3
18 | EOF
19 | # rearranjando a entrada para o proj4 com AWK
20 | cat << EOF | awk '{ print $3, $2, $4, $1 }' | \
21 | proj +proj=utm +zone=22 +north +ellps=WGS84 -f "%.3f"
22 | bueiro4 25.377403802778 -49.308814219444 917.219
23 | prego4 25.3778093722 -49.30913235 919.430
24 | EOF
25 |
26 | exit 0
27 |
--------------------------------------------------------------------------------
/shell/rotac_nuvemptos.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # GPL2 by yjmenezes at gmail.com versao 1.0
3 | # cloud point rotation arround a pivot point.
4 | # depends: bc - An arbitrary precision calculator language
5 | if [ $# -lt 1 ]
6 | then
7 | echo $(basename $0)" < inputfile.pxyz rot_ang_ddeg_with_sinal [px] [py]" 1>&2
8 | echo "px,py=pivot coordinates +CW, -CCW" 1>&2
9 | exit 1
10 | fi
11 | pi_=$(echo "scale=10; 4*a(1)" | bc -l)
12 | alfa_rad_=$(echo "$1 * $pi_ / 180.0 " | bc -l)
13 | si=$(echo "s($alfa_rad_)" | bc -l)
14 | co=$(echo "c($alfa_rad_)" | bc -l)
15 | if [ $# -ge 3 ]
16 | then
17 | px=$2
18 | py=$3
19 | else
20 | px=0.0
21 | py=0.0
22 | fi
23 | echo $1 $px $py $alfa_rad_ $pi_ $si $co 1>&2
24 | cat << EOF > test.pxyz
25 | a 1 1 1
26 | b 2 2 2
27 | c 3 3 3
28 | EOF
29 | # filter comments and process input file
30 | # si co px py pto x y z
31 | #cat test.pxyz | grep -v \# | while read lin; do
32 | grep -v -e ^$ -e \# | while read lin; do
33 | echo $si $co $px $py $lin | \
34 | awk '{ printf "%s\t%.3f\t%.3f\t%.3f\n", $5, (($6-$3) * $2 - ($7-$4) * $1) + $3, (($6-$3) * $1 + ($7-$4) * $2) + $4, $8 }'
35 | done
36 | exit 0
37 |
--------------------------------------------------------------------------------
/python/pypgis/connect.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #http://www.postgresqltutorial.com/postgresql-python/connect/
3 | import psycopg2
4 | from config import config
5 |
6 | def connect():
7 | """ Connect to the PostgreSQL database server """
8 | conn = None
9 | try:
10 | # read connection parameters
11 | params = config()
12 |
13 | # connect to the PostgreSQL server
14 | print('Connecting to the PostgreSQL database...')
15 | conn = psycopg2.connect(**params)
16 |
17 | # create a cursor
18 | cur = conn.cursor()
19 |
20 | # execute a statement
21 | print('PostgreSQL database version:')
22 | cur.execute('SELECT version()')
23 |
24 | # display the PostgreSQL database server version
25 | db_version = cur.fetchone()
26 | print(db_version)
27 |
28 | # close the communication with the PostgreSQL
29 | cur.close()
30 | except (Exception, psycopg2.DatabaseError) as error:
31 | print(error)
32 | finally:
33 | if conn is not None:
34 | conn.close()
35 | print('Database connection closed.')
36 |
37 |
38 | if __name__ == '__main__':
39 | connect()
40 |
--------------------------------------------------------------------------------
/python/scripts/generate_label/generate_label.py:
--------------------------------------------------------------------------------
1 | # Created By kyle felipe
2 | # Contact kylefelipe at gmail.com
3 | # Created At: 2022 - 06 - 13
4 |
5 | # A camada a ser usada como base precisa estar ativa (selecionada) no painel de
6 | # camadas
7 |
8 | virtual_layer_name = 'nova_camada_virtual' #Nome da camada virtual a ser gerada
9 | new_column = 'rotulo' # Nome do campo novo
10 | prefix = 'A - ' # prefixo do campo novo - esta linha nao pode ser removida
11 | sufix = '' # Sufixo - esta linha nao pode ser removida
12 | dest_EPSG = 31983
13 |
14 | project = QgsProject.instance()
15 | v_layer_id = QgsExpressionContextUtils.projectScope(project).variable('v_layer_id')
16 |
17 | # Remove a camada virtual, caso ja tenha sido criada
18 | if v_layer_id:
19 | project.removeMapLayer(v_layer_id)
20 |
21 | # Pega a camada ativa como base
22 | origin = iface.activeLayer()
23 |
24 |
25 | SQL = f"""SELECT l.*, '{prefix}' || """
26 | SQL += f"""row_number() OVER( ORDER BY area(ST_transform(l.geometry, {dest_EPSG})) ASC )"""
27 | SQL += f"""|| '{sufix}' as {new_column}"""
28 | SQL += f""" FROM "{origin.id()}" as l;"""
29 | dest_vector = QgsVectorLayer(f"?query={SQL}", virtual_layer_name, "virtual" )
30 | QgsProject.instance().addMapLayer(dest_vector)
31 | QgsExpressionContextUtils.setProjectVariable(project, 'v_layer_id', dest_vector.id())
32 |
--------------------------------------------------------------------------------
/python/shp2spatialite/shp2spatialite.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | # Python 2
4 |
5 | import os
6 | from sqlite3 import dbapi2 as db
7 |
8 |
9 | db_folder = "/home/x12239181/qgis-tips-tricks/python/shp2spatialite/"
10 | db_name = "test"
11 | shp_folder = "/home/x12239181/qgis-tips-tricks/python/shp2spatialite/territorios"
12 | table_name = "territorio"
13 | encoding = "WINDOWS-1252"
14 | srid = "4326"
15 |
16 | """Ceating Database"""
17 | print "Creating Database..."
18 | os.putenv("SPATIALITE_SECURITY", "relaxed")
19 | conn = db.connect(db_folder + db_name + ".sqlite")
20 | conn.enable_load_extension(True)
21 | conn.execute("SELECT load_extension('mod_spatialite')")
22 | # Init Spatial Metadata
23 | conn.execute('SELECT InitSpatialMetadata(1)')
24 | conn.commit()
25 |
26 | """Import a ESRI Shapefile to a SPATIALITE database
27 | shp_folder = Full path to Esri Shapefile, don't use .shp on shapefile name
28 | table_name = name to imported ESRI Shapefile
29 | encoding = SPH atribute table encoding
30 | srid = System Coordinate ID in proj4"""
31 |
32 | cur = conn.cursor()
33 | sql = """SELECT ImportSHP("{shp_folder}", "{table_name}", '{encoding}', {srid});"""\
34 | .format(shp_folder=shp_folder, table_name=table_name, encoding=encoding, srid=srid)
35 | cur.executescript(sql)
36 | conn.commit()
37 | conn.close()
38 |
39 |
40 |
--------------------------------------------------------------------------------
/python/processing_scripts/generate_label/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - generate_label
2 | _QGIS VERSION:_ 3.xx.xx
3 | _Processing toolbox_
4 |
5 | Esse script gera uma nova camada virtual com a nova coluna com o rótulo da feição, ordenada pela área da geometria, sendo possível colocar um prefixo e um sufixo.
6 |
7 | O novo campo receberá uma string (texto) no seguinte formato:
8 |
9 | ``
10 | sendo a ordem
11 |
12 | USAGE:
13 |
14 | Na caixa de ferramentas do processing clique no icone do [Python](www.python.org) e crie um novo script, cole o conteúdo do arquivo [generate_label.py](./generate_label.py) dentro da janela e salve.
15 |
16 | ## PARAMETROS
17 |
18 | * `Input Layer` camada vetorial a ser usada como base, apenas polígonos.
19 | * `Field name` Nome do campo a ser criado com o label novo
20 | * `Label Prefix` Prefixo a ser usando na label da feição
21 | * `Label Sufix` Sufixo a ser usando na label da feição
22 | * `Ascending` Se a ordem será feita no sentido ASCENDENTE (marcado) ou DESCENDENTE (desmarcado)
23 | * `CRS`: SRC que será usado para calculo de área, padrão é o EPSG: 31983
24 |
25 | ## CAMPOS DE SAIDA
26 |
27 | O output terá 2 campos adicionados.
28 |
29 | * `new_position`: recebe a nova posição da feição após a ordenação.
30 | * ``: Esse campo é definido pelo input __FIELD NAME__ e seu padrão é __new_label__
31 |
--------------------------------------------------------------------------------
/python/funcoes_qgis/padroniza_data.py:
--------------------------------------------------------------------------------
1 | @qgsfunction(args=2, group='Date and Time')
2 | def padroniza_data(values, feature, parent):
3 | """padroniza as datas de um campo do qgis para o seguinte formato aaaa-mm-dd.
4 | Syntax
padroniza_data(separador,data)
5 | SEPARADOR = simbolo separador utilizado na data que está errada (Exemplo: ',').
6 | DATA = Valor de data ou o campo com a data errada.
7 | Example
padroniza_data('/', "01/jan/2017 )-> 2017-01-01
8 | """
9 | meses = {'JANEIRO': '01', 'FEVEREIRO': '02', 'MARÇO': '03', 'ABRIL': '04', 'MAIO': '05', 'JUNHO': '06',
10 | 'JULHO': '07', 'AGOSTO': '08', 'SETEMBRO': '09', 'OUTUBRO': '10', 'NOVEMBRO': '11', 'DEZEMBRO': '12'}
11 | str_data = str(values[1])
12 | if len(str_data.split(values[0])) == 3:
13 | dia, mes, ano = str_data.split(values[0])
14 | if str.isdigit(mes.encode("utf8")) is False:
15 | for i in meses.iterkeys():
16 | if mes[:3].upper() == i[:3]:
17 | return "{ano}-{mes}-{dia:02d}".format(ano=ano, mes=meses[i], dia=int(dia))
18 | else:
19 | return "{ano}-{mes:02d}-{dia:02d}".format(ano=ano, mes=int(mes), dia=int(dia))
20 | else:
21 | return "Null"
22 |
--------------------------------------------------------------------------------
/python/scripts/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON - SCRIPTS
2 |
3 | Scripts feitos para rodar no terminal python do qgis
4 | Assista ao vídeo de como utilizar scripts python no QGIS:
5 | [](https://www.youtube.com/watch?v=0kaYuPeM0wI)
6 |
7 |
8 | * [salva_camadas](./salva_camadas): Esse script salva todas as camadas do projeto em um arquivo kml dentro das pastas das respectivas camadas (não funciona em camadas de texto delimitado).
9 | * [save_selected](./save_selected): Esse script seleciona dentro de cada camada do projeto feições usando uma expressão (feita na calculadora de campo) e salva a seleção em um arquivo, dentro da pasta da camada.
10 | * [vector_layers_attribute_txt](./scripts/vector_layers_attribute_txt): Esse script exporta todos os campos e seus tipos de cada camada vetorial ou tabular para um arquivo TXT.
11 | * [reorder_vertices](./reorder_vertices): Esse script gera uma nova camada de pontos com os vértices de um polígonos, reordenando ele a partir de um vértice escolhido.
12 | * [generate_label](./generate_label): Esse script gera uma nova camada virtual com a nova coluna com o rótulo da feição, ordenada pela área da geometria.
13 | * [load_functions](./load_functions): Esse script faz o registro das funções inseridas nele quando o QGIS é iniciado.
14 | * [Add Serviços SIGEF](./sigef_services/): Esse script adiciona os geoserviços do SIGEF no QGIS.
15 |
--------------------------------------------------------------------------------
/shell/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - SHELL
2 | Dicas e truques a serem usadas utilizando SHELL.
3 |
4 | * [cria_dtm_gdal.sh](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/cria_dtm_gdal.sh): cria DTM raster a partir de nuvem de pontos aleatorios X Y Z.
5 | * [csv2shp_ogr_point.sh](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/csv2shp_ogr_point.sh): cria shapefile a partir de texto CSV com Lat/Lon e atributos.
6 | * [pgis2geopkg.sh](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/pgis2geopkg.sh): Exporta padrao OGC GEOPACKAGE a partir de banco de dados PostGIS.
7 | * [pgis2shp.sh](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/pgis2shp.sh): Exporta como shapefile a partir de banco de dados PostGIS.
8 | * [proj4_geo2utm.sh](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/proj4_geo2utm.sh): Uso do PROJ4 para converter Lat/Lon(decimais com sinal) em UTM.
9 | * [raio_curv.awk](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/raio_curv.awk): Calcula o raio de curvatura dada a Latitude em graus decimais com sinal algebrico.
10 | * [rm_amazon](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/rm_amazon.sh): Remove os softwares spyware Amazon do UBUNTU GNU/Linux.
11 | * [shp2pgsql](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/shell/shp2pgsql.md): Insere todos os shapefiles de um diretorio em um banco Postgis.
12 |
13 | > "Use the SHELL, Luke" - Programador YODA
14 |
15 |
--------------------------------------------------------------------------------
/python/scripts/load_functions/startup.py:
--------------------------------------------------------------------------------
1 | # Criado por Kyle Felipe
2 | # Data: 2022/09/16
3 | # Esse script foi criado para que as funções do QGIS do usuário sejam registadas
4 | # na inicialização do programa.
5 | # Faça os imports necessários da sua função e coloque-a nesse script e insira o
6 | # nome da função na tupla functions_to_load
7 | # esse arquivo pode ser colocado nas pastas indicadas pela documentação do QGIS
8 | # https://docs.qgis.org/3.22/en/docs/pyqgis_developer_cookbook/intro.html?highlight=startup#running-python-code-when-qgis-starts
9 | # o nome do arquivo precisa ser startup.py, pois é o nome que o QGIS vai procurar
10 |
11 | from qgis.utils import qgsfunction
12 |
13 | from qgis.core import *
14 | from qgis.gui import *
15 |
16 | @qgsfunction(args='auto', group='Hebert Azevedo')
17 | def retira_acento(value1, feature, parent):
18 | """Função criada por Herbert Azevedo
19 | https://groups.google.com/g/qgisbrasil/c/nzP3gfJo5KM
20 | """
21 |
22 | listaa = 'àáâãäèéêëìíîïòóôõöùúûüÀÁÂÃÄÈÉÊËÌÍÎÒÓÔÕÖÙÚÛÜçÇñÑ '
23 |
24 | listab = 'aaaaaeeeeiiiiooooouuuuAAAAAEEEEIIIOOOOOUUUUcCnN '
25 |
26 | k = 0
27 |
28 | for caract in listaa:
29 | value1 = value1.replace(caract, listab [k])
30 | k += 1
31 |
32 | return value1
33 |
34 | functions_to_load = (retira_acento,)
35 |
36 | def registerFunction(isRegister=True):
37 | """Registra as funções para uso no qgis"""
38 | for f in functions_to_load:
39 | QgsExpression.registerFunction(f)
40 |
41 | registerFunction()
42 |
--------------------------------------------------------------------------------
/python/ogr_shp2kml/ogr_shp2kml.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Author: Kyle Felipe Vieira Roberto
3 | # E-mail: kylefelipe@gmail.com
4 | # Date: 2018/05/22
5 |
6 | import os, sys
7 | from os import sep as separador
8 | from subprocess import call
9 |
10 | format_in = ".shp"
11 |
12 | def list_path(path):
13 | """ Get all sub-paths from a path if have a shapefile inside"""
14 | path_lits = []
15 | for path, directory, files in os.walk(path):
16 | for file_in in files:
17 | if file_in.lower().endswith(format_in):
18 | path_lits.append(path+separador+file_in)
19 | if len(path_lits) > 0:
20 | return set(path_lits)
21 | else:
22 | return False
23 |
24 |
25 | def save_kml(file_in):
26 | """ Change savinf file shp to kml """
27 | file_out = file_in[:-4]+".kml"
28 | pasta = str.join(separador, file_in.split(separador)[:-1])
29 | print "salvando arquivo {arquivo} na pasta {pasta}".format(arquivo=file_in.split(separador)[-1], pasta=pasta)
30 | command = "ogr2ogr", "-f","KML", """{arquivosaida}""".format(arquivosaida=file_out), """{file_in}""".format(file_in=file_in)
31 | call(command)
32 |
33 |
34 | try:
35 |
36 | if len(sys.argv) > 1:
37 | print "Caminho:", sys.argv[1]
38 | if os.path.isdir(sys.argv[1]):
39 | if list_path(sys.argv[1]) is not False:
40 | for path in list_path(sys.argv[1]):
41 | save_kml(path)
42 | else:
43 | print("No files with the extension '{}' was found!!!".format(format_in))
44 | else:
45 | print("Argument is not a valid path!")
46 |
47 | except:
48 | print("Inform a valid path to use!!!")
--------------------------------------------------------------------------------
/python/README.md:
--------------------------------------------------------------------------------
1 | # QGIS tips & tricks - PYTHON
2 | Dicas e truques a serem usadas no qgis, utilizando python.
3 |
4 | * [change_encode](./python/change_encode): Script _Python_ que roda o comando ogr2ogr nos arquivos dentro de um diretório e dentro de seus sub diretórios fazendo a mudança de encode.
5 | * [csv2postgis](./python/csv2postgis): Script _Python 3_ que importa um CSV para o Postgis e faz união com uma tabela georreferenciada.
6 | * [funcoes_qgis](./python/funcoes_qgis): funções desenvolvidas em PYTHON 2.7 a serem utilizadas nas expressões do QGIS.
7 | * [gdal_recursive](./python/gdal_recursive): Script _Python_ que roda o comando gdal_translate nos arquivos dentro de um diretório e dentro de seus sub diretórios.
8 | * [gridpoints](./python/gridpoints): Script _Python_ que gera uma malha (grid) de pontos.
9 | * [paralelas](./python/paralelas): script python que utiliza um banco de dados [SPATIALITE](http://www.gaia-gis.it/gaia-sins/spatialite-cookbook/index.html) para gerar gerar linhas paralelas.
10 | * [select_unique](./python/select_unique): Seleciona feições com atributos únicos em um campo da tabela de atributos.
11 | * [ogr_shp2kml](./python/ogr_shp2kml): converte para KML os arquivos .shp que estiverem dentro de um diretório e seus sub diretórios.
12 | * [Scripts](./python/scripts): Scripts que podem ser rodados pelo terminal python do Qgis
13 | * [reproj_recursive](./python/reproj_recursive): Script _Python_ que roda o comando ogr2ogr nos arquivos dentro de um diretório e dentro de seus sub diretórios fazendo a mudança de src.
14 | * [Processing Scripts](./processing_scripts): Scripts que podem ser adicionados à caixa de ferramenta do [QGIS](www.qgis.org)
15 |
16 | > "Always look on the bright side of life..." - Monthy Python
17 |
--------------------------------------------------------------------------------
/shell/csv2shp_ogr_point.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #GPL2 by yjmenezes at gmail.com versao 1.0 $2011-08-10
3 | # http://www.gdal.org/ogr/drv_vrt.html
4 | # CSV to SHP WGS84=EPSG:4326
5 | # alguns testes com arquivos CSV e preparacao para o QuantumGIS
6 | # dependencias: sudo apt-get update; apt-get install gdal-bin
7 | echo $(basename $0) 1>&2
8 | MY_DIR=/tmp
9 | cd $MY_DIR
10 | rm mylayer* sample*
11 | # criando um arquivo de dados de exemplo com 4 campos, poderiam ser mais.
12 | # linha 1 contem nome dos campos, e deve ser coerente com o arquivo *vrt
13 | cat << eof | grep -v ^\# > sample1_g84.csv
14 | longgg,latggg,pname,z
15 | -49.29,-25.39,p01,960.0
16 | -49.29,-25.37,p02,961.0
17 | -49.32,-25.37,p03,962.0
18 | -49.32,-25.39,p04,963.0
19 | eof
20 | # converte de csv para dbf
21 | # ogr2ogr -f "ESRI Shapefile" $MY_DIR sample1_g84.csv
22 | # cria arquivo vrt (virtual format) descrevendo os dados de entrada
23 | cat << eof > sample1_g84.vrt
24 |
25 |
26 | $MY_DIR
27 | sample1_g84
28 | wkbPoint
29 | WGS84
30 |
31 |
32 |
33 | eof
34 | # transforma em shp
35 | ogr2ogr -f "ESRI Shapefile" $MY_DIR sample1_g84.vrt
36 | # lista as informacoes
37 | ogrinfo -al mylayer1_g84.shp
38 | # transtorma em UTM
39 | ogr2ogr -t_srs "+proj=utm +zone=22 +south +datum=WGS84" mylayer1_u84.shp mylayer1_g84.shp -nlt POINT
40 | # listando as informacoes em UTM
41 | ogrinfo -al mylayer1_u84.shp
42 | # gerando o kml
43 | ogr2ogr -f "KML" -t_srs EPSG:4326 mylayer1_g84.kml mylayer1_g84.shp
44 | exit 0
45 | # some ideas from: http://casoilresource.lawr.ucdavis.edu/drupal/book
46 |
47 |
--------------------------------------------------------------------------------
/python/scripts/reorder_vertices/reorder_vertices.py:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | ## Reordena vertices
3 | ## É necessário que haja uma camada de poligonos ativa
4 | ## e um vetor selecionado na camada
5 | ## Criado por Kyle Felipe
6 | ## kylefelipe at gmail.com
7 | ## Criado em 2022/05/30
8 | ###############################################################################
9 |
10 | layer = iface.activeLayer()
11 | features = layer.getSelectedFeatures()
12 |
13 | # Criando uma camada temporária para receber os vértices
14 | tempVp = QgsVectorLayer(f"Point?crs={layer.crs().authid()}", "temporary_points", "memory")
15 | QgsProject.instance().addMapLayer(tempVp)
16 | dpTempVp = tempVp.dataProvider()
17 |
18 | id_vertex = 2 # Edite aqui ID do Vértice onde deseja iniciar a ordenação
19 | topo = 'T' # Edite aqui o texto que deseja que vá antes do nome do número do vérice
20 |
21 | # Criando campo para receber nome do vértice e o tipo do vérice
22 |
23 | campos = [QgsField('toponimia', QVariant.String), QgsField('tipo', QVariant.String)]
24 | tempVp.dataProvider().addAttributes(campos)
25 | tempVp.updateFields()
26 |
27 | def ordenaPoligono(pol, id_escolhido=0):
28 | """Essa função reordena os vertices e retorna uma nova lista"""
29 | return pol[id_escolhido:] + pol[1: id_escolhido]
30 |
31 |
32 | for f in features:
33 | # pegando a geometria da feição
34 | geom = f.geometry()
35 | polygon = geom.asPolygon()
36 | ordered = ordenaPoligono(polygon[0], id_vertex)
37 | # Adicionando os pontos na camada temporária criada anteriormente
38 | for i in ordered:
39 | feicaoPonto = QgsFeature(tempVp.fields())
40 | feicaoPonto.setGeometry(QgsGeometry.fromPointXY(i))
41 | attributos = [f"{topo}{ordered.index(i)}"]
42 | feicaoPonto.setAttributes(attributos)
43 | dpTempVp.addFeature(feicaoPonto)
44 |
45 |
46 | tempVp.updateExtents()
47 | print("Terminado")
48 |
--------------------------------------------------------------------------------
/python/scripts/save_selected/save_selected.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from os import sep
4 | layers = iface.legendInterface().layers()
5 | exp = QgsExpression("""field_3 = 12.2253 or $id = 3""")
6 | new_layers = []
7 | root = QgsProject.instance().layerTreeRoot()
8 | node_group = root.insertGroup(0, "DADOS_FILTRADOS")
9 |
10 |
11 | def where(layer, exp):
12 | """Font https://docs.qgis.org/2.18/pt_BR/docs/pyqgis_developer_cookbook/
13 | expressions.html#expressions"""
14 | layers = list(layer.getFeatures())
15 | id = []
16 | if exp.hasParserError():
17 | raise Exception(exp.parserErrorString())
18 | exp.prepare(layer.pendingFields())
19 | for feature in layers:
20 | value = exp.evaluate(feature)
21 | if exp.hasEvalError():
22 | raise ValueError(exp.evalErrorString())
23 | if bool(value):
24 | id.append(layers.index(feature))
25 | return id
26 |
27 |
28 | for layer in layers:
29 | # Select features in layer
30 | # cleaning previous selection
31 | layer.setSelectedFeatures([])
32 | layer.setSelectedFeatures(where(layer, exp))
33 | folder_path = str(layer.source()).split(sep)[:-1]
34 | file = layer.name()+"_DadoFiltrado"
35 | layer_out = sep.join(folder_path)+sep+file
36 | layerType = layer.type()
37 | if layerType == QgsMapLayer.VectorLayer:
38 | QgsVectorFileWriter.writeAsVectorFormat(layer,
39 | r"{out}".format(out=layer_out),
40 | "utf-8", None, "ESRI Shapefile"
41 | , True)
42 | new_layers.append(layer_out)
43 | # print r"{saida}".format(saida=file)
44 |
45 | for i in new_layers:
46 | name = i.split(sep)[-1]
47 | layer = QgsVectorLayer(i+".shp", name, "ogr")
48 | QgsMapLayerRegistry.instance().addMapLayer(layer, False)
49 | node_group.addLayer(layer)
50 |
51 | print "{d} layers inserted.".format(d=len(new_layers))
52 |
--------------------------------------------------------------------------------
/python/change_encode/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - PYTHON - change_encode
2 |
3 | ### Autor: Kyle Felipe
4 | ### Data: 13/03/2018
5 |
6 | O script surgiu de uma necessidade de mudar o encoding de diversos arquivos shapefiles, dentro de pastas e suas sub pastas para um determinado ENCODING.
7 | A intenção é, utilizar o comando [ogr2ogr](http://www.gdal.org/ogr2ogr.html) nos arquivos que estiverem dentro de pastas e subpastas, utilizando __Python__.
8 | A transformação só será feita nos formatos VETORIAIS de arquivos que baterem com o informado.
9 | O arquivo transformado é gerado na mesma pasta do arquivo original.
10 |
11 | Como exemplo, o script procura por um aquivo .shp dentro das pastas e o muda encoding para UTF-8
12 |
13 | Pode ser utilizado no _Python 2_ ou superior, e é necessária a instalação do pacote osgeo.
14 |
15 | ## Modo de uso
16 |
17 | python change_encode.py <"endereço_da_pasta">
18 | : deve ser substituido pelo ENCODING desejado sempre informado ente aspas duplas "".
19 | <"endereço_da_pasta"> o endereço absoluto da pasta que deseja rodar a transformação, sempre deve ser informada entre aspas duplas "".
20 |
21 | * Exemplo: > python change_encode.py "UTF-8" "/home/temp"
22 |
23 |
24 | ## change_encode.py
25 |
26 | É o arquivo principal, contendo todo as funções do Python necessárias para rodar o comando ogr2ogr.
27 | contem uma variável globai e as funções utilizadas:
28 |
29 | * _Variável_ format_in: É a extensão do formato a a ter o ENCODING mudado.
30 |
31 | * list_path(path): É a função que verifica as pastas que possuem arquivos com a extensão informada na variável format_in, ela precisa de um caminho (path) para analizar, e retorna uma lista com as pastas que possuem arquivos que batem com a extensão.
32 | * find_file(path): É a função que procura dentro da pasta os arquivos que batem com a extensão.
33 | * run_ogr2ogr(file_in, encode): É a função que roda o comando ogr2ogr para cada arquivo dentro da pasta.
34 |
35 | Os códigos podem ser alterados conforme a necessidade de utilização.
36 |
--------------------------------------------------------------------------------
/python/gridpoints/gridpoints.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | '''
3 | Created on 9 de mar de 2018
4 |
5 | @author: Jorge Luiz Santos
6 | '''
7 | import sys
8 | from curses.ascii import isdigit
9 |
10 | def uso():
11 | sys.stderr.write ('Digite apenas numeros\n')
12 | sys.stderr.write ('''
13 | Uso:
14 | python gridpoints
15 | Onde: origem = canto superior esquerdo, ver sinal algebrico na linha 44
16 | x0 => Float para coordenada X inicial;
17 | y0 => Float para coordenada Y inicial;
18 | número de colunas => Inteiro para o número de colunas;
19 | número de linhas => Inteiro para o número de linhas;
20 | distância => Float para distância entre os pontos do grid
21 | ''')
22 | sys.exit(1)
23 |
24 | def verificaArgumentos():
25 | if len(sys.argv) != 6:
26 | uso()
27 |
28 | for i in range(1, len(sys.argv)):
29 | try:
30 | float(sys.argv[i])
31 | except ValueError:
32 | sys.stderr.write('Erro no parâmetro %i: %s\n' %(i, sys.argv[i]))
33 | return False
34 |
35 | return True
36 |
37 |
38 | def gridPoints(coordIni, numCol, numRow, dist):
39 | x0,y0 = coordIni
40 |
41 | sys.stdout.write("X,Y\n")
42 | for row in range(numRow):
43 | for col in range(numCol):
44 | sys.stdout.write('%.3f,%.3f\n'%(x0 + col * dist, y0 - row * dist))
45 |
46 |
47 | def main():
48 | if not verificaArgumentos():
49 | uso()
50 | sys.exit(1)
51 |
52 | coordIni = (float(sys.argv[1]), float(sys.argv[2]))
53 | numCol = int(sys.argv[3])
54 | numRow = int(sys.argv[4])
55 | dist = float(sys.argv[5])
56 |
57 | gridPoints(coordIni, numCol, numRow, dist)
58 |
59 | sys.stderr.write('Programa terminado\n')
60 | sys.exit(0)
61 |
62 | if __name__ == "__main__":
63 | main()
64 |
--------------------------------------------------------------------------------
/python/reproj_recursive/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - PYTHON - change_encode
2 |
3 | ### Autor: Kyle Felipe
4 | ### Data: 17/07/2018
5 |
6 | O script surgiu de uma necessidade de mudar o SRC de diversos arquivos shapefiles, dentro de pastas e suas sub pastas para um determinado SRC.
7 | A intenção é, utilizar o comando [ogr2ogr](http://www.gdal.org/ogr2ogr.html) nos arquivos que estiverem dentro de pastas e subpastas, utilizando __Python__.
8 | A transformação só será feita nos formatos VETORIAIS de arquivos que baterem com o informado.
9 | O arquivo transformado é gerado na mesma pasta do arquivo original.
10 |
11 | Como exemplo, o script procura por um aquivo .shp dentro das pastas e o muda src para EPSG:4674
12 |
13 | Pode ser utilizado no _Python 2_ ou superior, e é necessária a instalação do pacote osgeo.
14 |
15 | ## Modo de uso
16 |
17 | python reproj_recursive.py <"endereço_da_pasta">
18 | : deve ser substituido pelo SRC desejado sempre informado ente aspas duplas "".
19 | <"endereço_da_pasta"> o endereço absoluto da pasta que deseja rodar a transformação, sempre deve ser informada entre aspas duplas "".
20 |
21 | * Exemplo: > python reproj_recursive.py "EPSG:4677" "/home/temp"
22 |
23 |
24 | ## reproj_recursive.py
25 |
26 | É o arquivo principal, contendo todo as funções do Python necessárias para rodar o comando ogr2ogr.
27 | contem uma variável globai e as funções utilizadas:
28 |
29 | * _Variável_ format_in: É a extensão do formato a a ter o src mudado.
30 | * _Variável_ insrs: É a variável que armazena o SRS novo.
31 |
32 | * list_path(path): É a função que verifica as pastas que possuem arquivos com a extensão informada na variável format_in, ela precisa de um caminho (path) para analizar, e retorna uma lista com as pastas que possuem arquivos que batem com a extensão.
33 | * find_file(path): É a função que procura dentro da pasta os arquivos que batem com a extensão.
34 | * run_ogr2ogr(file_in, srs): É a função que roda o comando ogr2ogr para cada arquivo dentro da pasta.
35 |
36 | Os códigos podem ser alterados conforme a necessidade de utilização.
37 |
--------------------------------------------------------------------------------
/python/gdal_recursive/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - PYTHON - gdal_recursive
2 |
3 | ### Autor: Kyle Felipe
4 | ### Data: 06/03/2018
5 |
6 | O script surgiu de uma necessidade de um colega no grupo do [Qgis Brasil](https://groups.google.com/forum/#!forum/qgisbrasil).
7 | A intenção é, utilizar o comando [gdal_translate](http://www.gdal.org/gdal_translate.html) nos arquivos que estiverem dentro de pastas e subpastas, utilizando __Python__.
8 | A transformação só será feita nos formatos de arquivos que baterem com o informado.
9 | O arquivo transformado é gerado na mesma pasta do arquivo original.
10 |
11 | Como exemplo, o script procura por um aquivo .asc dentro das pastas e o trasnforma para o GTiff
12 |
13 | Pode ser utilizado no _Python 2_ ou superior, e não é necessária a instalação de nenhum pacote adicional.
14 |
15 | ## Modo de uso
16 |
17 | python gdal_recursive.py <"endereço_da_pasta">
18 | : deve ser substituido pelo número do EPSG utilizado nos arquivos que deseja fazer a transformação
19 | <"endereço_da_pasta"> o endereço absoluto da pasta que deseja rodar a transformação, sempre deve ser informada entre aspas duplas "".
20 |
21 | * Exemplo: > python gdal_recursive.py 4674 "/home/temp"
22 |
23 |
24 | ## gdal_recursive.py
25 |
26 | É o arquivo principal, contendo todo as funções do Python necessárias para rodar o comando gdal_translate.
27 | contem duas variáveis globais e as funções utilizadas:
28 |
29 | * _Variável_ format_in: É a extensão do formato a ser transformado.
30 | * _Variável_ format_out: É a extensão do formato transformado que foi gerado.
31 |
32 | * list_path(path): É a função que verifica as pastas que possuem arquivos com a extensão informada na variável format_in, ela precisa de um caminho (path) para analizar, e retorna uma lista com as pastas que possuem arquivos que batem com a extensão.
33 | * find_file(path): É a função que procura dentro da pasta os arquivos que batem com a extensão.
34 | * run_gdal(epsg, file_path, file): É a função que roda o comando gdal_translate para cada arquivo dentro da pasta.
35 |
36 | Os códigos podem ser alterados conforme a necessidade de utilização.
37 |
--------------------------------------------------------------------------------
/python/gdal_recursive/gdal_recursive.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Author: Kyle Felipe Vieira Roberto
3 | # E-mail: kylefelipe@gmail.com
4 | # Date: 2018/03/06
5 |
6 | import os, sys
7 | from subprocess import call
8 |
9 |
10 | format_in = ".tif"
11 | format_out = ".tif"
12 |
13 |
14 | def list_path(path):
15 | """ Get all sub-paths from a path if have a tiff inside"""
16 | path_lits = []
17 | # print("list_path:", path)
18 | for path, directory, files in os.walk(path):
19 | for file in files:
20 | if file.lower().endswith(format_in):
21 | path_lits.append(path)
22 | # print(set(path_lits))
23 | if len(path_lits) > 0:
24 | return set(path_lits)
25 | else:
26 | return False
27 |
28 |
29 | def find_file(path):
30 | path_tiff = []
31 | for i in os.listdir(path):
32 | if i.lower().endswith(format_in):
33 | path_tiff.append(i)
34 | return path_tiff
35 |
36 |
37 | def run_gdal(epsg, file_path, file):
38 | """Run gedal process"""
39 | file_in = file_path+"/"+file
40 | # print("Entrada:", file_in)
41 | # print(str.split(file, "."))
42 | file_out = file_path+"/"+(str.split(file, ".")[0])+"_translate.tif"
43 | # print("Saida:", file_out)
44 | command = "gdal_translate", "-a_srs", "EPSG:{}".format(epsg), "-of", "GTiff", file_in, file_out
45 | print(command)
46 | call(command)
47 |
48 |
49 | try:
50 | # print(len(sys.argv))
51 | if len(sys.argv) > 1:
52 | if os.path.isdir(sys.argv[2]):
53 | epsg = sys.argv[1]
54 | # print(">: ", list_path(sys.argv[2]))
55 | print(sys.argv[2])
56 | if list_path(sys.argv[2]) is not False:
57 | for path in list_path(sys.argv[2]):
58 | # print(">>:", path)
59 | for file in find_file(path):
60 | run_gdal(epsg, path, file)
61 | else:
62 | print("No files with the extension '{}' was found!!!".format(format_in))
63 | else:
64 | print("Argument is not a valid path!")
65 |
66 | except:
67 | print("Inform a valid path to use!!!")
68 |
--------------------------------------------------------------------------------
/python/paralelas/linhas_paralelas.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python2.7
2 | # -*- coding: utf-8 -*-
3 | # author: yjmenezes cartognu.org 2017-06-27 QGIS
4 | # sudo apt-get update; sudo apt-get install python-pip
5 | # sudo pip intall --upgrade pip; sudo pip install sqlite3
6 | import sys
7 | import sqlite3.dbapi2 as db
8 | from os import putenv
9 |
10 |
11 | def usage():
12 | print """
13 | Script tosco mostrando como gerar paralelas de 1.45m usando Spatialite.
14 | ATENCAO: Precisa de um banco de dados paracatu.sqlite contendo a linha (LINESTRING) de referencia.
15 | """
16 |
17 |
18 | if __name__ == '__main__':
19 | try:
20 | putenv("SPATIALITE_SECURITY", "relaxed")
21 | con = db.connect('paracatu.sqlite')
22 | # loading extension on connect:
23 | con.enable_load_extension(True)
24 | con.execute("SELECT load_extension('mod_spatialite');")
25 | cursor = con.execute('SELECT sqlite_version(), spatialite_version()')
26 | dados = list(cursor.fetchall())
27 | # Output should be something like:[(3.8.7.1, 4.1.1)]
28 | print "SQLITE VERSION:", dados[0][0]
29 | print "SPATIALITE VERSION: ", dados[0][1]
30 |
31 | # Creating table paracatu_paralelas to receive the new lines. 32723=WGS84 UTM 23S
32 | con.executescript("""CREATE TABLE IF NOT EXISTS linhas_paralelas (id INTEGER PRIMARY KEY AUTOINCREMENT);
33 | SELECT AddGeometryColumn ('linhas_paralelas', 'geom', 32723, 'LINESTRING', 'XY');""")
34 | con.commit()
35 |
36 | # trator paralell lines, centimeter, for 130m range
37 | distancia = []
38 | # Linhas do lado esquerdo (negativo)
39 | for i in range(145, 13000, 145):
40 | distancia.append(((float(i)/100)*-1,))
41 | # linhas do lado direito (positivo)
42 | for i in range(145, 13000, 145):
43 | distancia.append(((float(i)/100),))
44 | # print distancia
45 | sql = """INSERT INTO linhas_paralelas(geom)
46 | SELECT ST_OffsetCurve(geometry, ?) from paracatu;"""
47 | con.executemany(sql,distancia)
48 | con.commit()
49 | con.close()
50 | print "Foram geradas {qt} linhas paralelas com sucesso....".format(qt=len(distancia))
51 |
52 |
53 | except:
54 | usage()
55 | sys.exit(0)
56 |
--------------------------------------------------------------------------------
/python/change_encode/change_encode.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Author: Kyle Felipe Vieira Roberto
3 | # E-mail: kylefelipe@gmail.com
4 | # Date: 2018/03/13
5 |
6 | import os, sys
7 | from osgeo import ogr
8 | from subprocess import call
9 |
10 | format_in = ".shp"
11 | insrs = '4326'
12 | outsrs = '4674'
13 |
14 |
15 | def list_path(path):
16 | """ Get all sub-paths from a path if they have a shapefile inside"""
17 | path_lits = []
18 | # print("list_path:", path)
19 | for path, directory, files in os.walk(path):
20 | for file_in in files:
21 | if file_in.lower().endswith(format_in):
22 | path_lits.append(path)
23 | # print(set(path_lits))
24 | if len(path_lits) > 0:
25 | return set(path_lits)
26 | else:
27 | return False
28 |
29 |
30 | def find_file(path):
31 | path_vector = []
32 | for i in os.listdir(path):
33 | if i.lower().endswith(format_in):
34 | path_vector.append(i)
35 | return path_vector
36 |
37 |
38 | def run_ogr2ogr(file_in, encode):
39 | """ Change shapefile srs using ogr2ogr """
40 | driver = ogr.GetDriverByName('ESRI Shapefile')
41 |
42 | # folder = str.join("/", (file_in.split("/")[:-1]))
43 | file_out = file_in[:-4]+"_srs"+file_in[-4:]
44 | file_out2 = file_out
45 |
46 | command = "ogr2ogr", "-lco", "ENCODING={to_encode}".format(to_encode=encode), "{file_out}".format(file_out=file_out2),\
47 | "{file_in}".format(file_in=file_in)
48 | call(command)
49 | return "{}".format(file_out2)
50 |
51 |
52 | try:
53 |
54 | if len(sys.argv) > 1:
55 | if os.path.isdir(sys.argv[2]):
56 | to_encode = sys.argv[1]
57 | if list_path(sys.argv[2]) is not False:
58 | for path in list_path(sys.argv[2]):
59 | # print(">>:", path)
60 | for file_in in find_file(path):
61 | file_in2 = path + "/" + file_in
62 | run_ogr2ogr(file_in=file_in2, encode=to_encode)
63 | print("Process finished...")
64 | else:
65 | print("No files with the extension '{}' was found!!!".format(format_in))
66 |
67 | else:
68 | print("Argument is not a valid path!")
69 |
70 | except:
71 | print("Inform a valid path to use!!!")
72 |
--------------------------------------------------------------------------------
/python/reproj_recursive/reproj_recursive.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Author: Kyle Felipe Vieira Roberto
3 | # E-mail: kylefelipe@gmail.com
4 | # Date: 2018/03/13
5 |
6 | import os, sys
7 | from osgeo import ogr
8 | from subprocess import call
9 |
10 | format_in = ".shp"
11 | outsrs = ''
12 |
13 |
14 | def list_path(path):
15 | """ Get all sub-paths from a path if they have a shapefile inside"""
16 | path_lits = []
17 | # print("list_path:", path)
18 | for path, directory, files in os.walk(path):
19 | for file_in in files:
20 | if file_in.lower().endswith(format_in):
21 | path_lits.append(path)
22 | # print(set(path_lits))
23 | if len(path_lits) > 0:
24 | return set(path_lits)
25 | else:
26 | return False
27 |
28 |
29 | def find_file(path):
30 | path_vector = []
31 | for i in os.listdir(path):
32 | if i.lower().endswith(format_in):
33 | path_vector.append(i)
34 | return path_vector
35 |
36 |
37 | def run_ogr2ogr(file_in, srs):
38 | """ Change shapefile srs using ogr2ogr """
39 | driver = ogr.GetDriverByName('ESRI Shapefile')
40 |
41 | # folder = str.join("/", (file_in.split("/")[:-1]))
42 | file_out = file_in[:-4]+"_srs"+file_in[-4:]
43 | file_out2 = file_out
44 |
45 | command = "ogr2ogr", "-t_srs", "{out_srs}".format(out_srs=srs),\
46 | "{file_out}".format(file_out=file_out2),\
47 | "{file_in}".format(out_srs=outsrs, file_in=file_in)
48 | call(command)
49 | return "{}".format(file_out2)
50 |
51 |
52 | try:
53 | if len(sys.argv) > 1:
54 | # print sys.argv[2]
55 | caminho = r'{}'.format(sys.argv[2])
56 | if os.path.isdir(caminho):
57 | outsrs = sys.argv[1]
58 | if list_path(sys.argv[2]) is not False:
59 | for path in list_path(sys.argv[2]):
60 | # print(">>:", path)
61 | for file_in in find_file(path):
62 | file_in2 = path + os.sep + file_in
63 | run_ogr2ogr(file_in=file_in2, srs=outsrs)
64 | print("Process finished...")
65 | else:
66 | print("No files with the extension '{}' was found!!!".format(format_in))
67 |
68 | else:
69 | print("Argument is not a valid path!")
70 |
71 | except:
72 | print("Informe argumentos válidos")
73 |
--------------------------------------------------------------------------------
/shell/cria_dtm_gdal.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #GPL2 by yjmenezes at gmail dot com ver 1.0 2014-09-29
3 | # exemplo de linha de comando para interpolar DTM dada uma nuvem X Y Z
4 | # ver 1.1 2017-03-14 filtrando Altitudes negativas com awk
5 | # http://www.gdal.org/grid_tutorial.html Thx Frank Wanerdan !
6 | rm -r /tmp/grid
7 | mkdir -p /tmp/grid
8 | echo "processamento em /tmp/grid" 1>&2
9 | cd /tmp/grid
10 | echo "exemplo: criando a nuvem de pontos, entrada tipica " 1>&2
11 | sleep 1
12 | cat << EOF | awk -F\, 'NR == 1 || $4 > 0 { print }'> nuvem3d.csv
13 | Ponto,X_e84,Y_n84,Altitude
14 | 4xxx,687091.302,7155418.977,-9782
15 | 4a,687124.000,7155353.000,101.25
16 | 4b,687113.950,7155353.017,102.34
17 | 4c,687084.497,7155355.534,107.48
18 | 4d,687089.976,7155376.635,98.34
19 | 4e,687095.562,7155392.043,103.14
20 | 4f,687090.302,7155410.613,97.23
21 | 4g,687060.338,7155411.855,99.46
22 | 4h,687045.285,7155417.977,105.24
23 | 4x,687090.302,7155417.977,-9782
24 | 4i,687038.536,7155449.391,103.78
25 | 4j,687084.365,7155464.227,98.87
26 | 4k,687190.263,7155492.394,106.45
27 | 4xx,687091.302,7155417.977,-9782
28 | 4l,687213.991,7155485.218,103.68
29 | 4m,687154.991,7155449.926,105.49
30 | 4n,687182.015,7155427.091,97.65
31 | 4o,687124.371,7155424.328,99.32
32 | EOF
33 | # passo 1: nome das colunas deve ser coerente com a linha header da nuvem3d.csv
34 | echo "1- criando virtual driver GDAL" 1>&2
35 | sleep 1
36 | cat << EOF > nuvem3d.vrt
37 |
38 |
39 | nuvem3d.csv
40 | wkbPoint
41 |
42 |
43 |
44 | EOF
45 | echo "veja os limites z " 1>&2
46 | grep -iv ponto nuvem3d.csv | sort -t\, -n -k 4
47 | echo "veja os limites x " 1>&2
48 | grep -iv ponto nuvem3d.csv | sort -t\, -n -k 2
49 | echo "veja os limites y " 1>&2
50 | grep -iv ponto nuvem3d.csv | sort -t\, -n -k 3
51 | #
52 | echo "2- interpolando e gerando raster, ( moldura txe tye ) definida abaixo" 1>&2
53 | sleep 1
54 | gdal_grid -zfield "Altitude" -a invdist:power=2.0:smoothing=1.0 -txe 687000 687250 -tye 7155300 7155500 -outsize 250 200 -of GTiff -ot Float64 -l nuvem3d nuvem3d.vrt dem.tiff --config GDAL_NUM_THREADS ALL_CPUS
55 | echo "3- interpolando curvas de nivel 1m" 1>&2
56 | sleep 1
57 | gdal_contour -a elev dem.tiff contour.shp -i 1.0
58 | exit 0
59 |
--------------------------------------------------------------------------------
/shell/gdal_tranlate.md:
--------------------------------------------------------------------------------
1 | # Comandos bash para converter varios rasters a diferentes extenções
2 |
3 | :warning: Comandos meramente ilustrativos. **Vários parâmetros dos comando [gdal_translate](https://www.gdal.org/gdal_translate.html) foram ignorados!**
4 |
5 | Considerando que temos vários rasters em um formato \*.asc (por exemplo) e queremos convertê-los a outro formato (no exemplo, TIFF), podemos proceder a seguinte forma:
6 |
7 | * Criar uma variável com o path aos rasters a serem convertidos;
8 | * Loop para executar para cada item dessa lista o *gdal_translate*;
9 |
10 | 1) Criando variável com lista de rasters a serem convertidos:
11 | No terminal (*bash/shell*), usaremos o comando *[find](https://www.gnu.org/software/findutils/manual/html_mono/find.html#find-Expressions)* para buscar os arquivos com padrão \*.asc e adicionaremos o resultado a uma variavel *raster*:
12 | ```
13 | # Identifying rasters to be translated to another extention
14 | raster="$(find . -name *.asc)"
15 | ```
16 | O ponto positivo em se usar o comando *find* é que ele é recursivo. Ou seja **os rasters ão precisam estar numa mesma pasta. Podem estar um subpastas diferentes**
17 |
18 | 2) Ainda no *terminal* vamos usar o *for* para iterar a cada raster, e executar o comando *gdal_translate*.
19 | O loop tem o seguinte padrão:
20 | ```
21 | for i in lista;
22 | do algum_comando;
23 | done;
24 | ```
25 | Como teste, podemos iterar a lista de raster e "printar" cada um deles:
26 | ```
27 | for i in $raster;
28 | do echo "O raster a ser convertido é: $raster";
29 | done;
30 | ```
31 | **Resultado esperado**
32 | ```
33 | $ for i in $raster; do echo "O raster a ser convertido é: $i"; done;
34 | O raster a ser convertido é: ./GRIP4_density_total/grip4_total_dens_m_km2.asc
35 | O raster a ser convertido é: ./GRIP4_density_tp1/grip4_tp1_dens_m_km2.asc
36 | O raster a ser convertido é: ./GRIP4_density_tp2/grip4_tp2_dens_m_km2.asc
37 | O raster a ser convertido é: ./GRIP4_density_tp3/grip4_tp3_dens_m_km2.asc
38 | O raster a ser convertido é: ./GRIP4_density_tp4/grip4_tp4_dens_m_km2.asc
39 | O raster a ser convertido é: ./GRIP4_density_tp5/grip4_tp5_dens_m_km2.asc
40 | ```
41 | Para a conversão, vamos remover o echo e incluir o gdal_translate. Ficando assim:
42 | ```
43 | for i in $raster; do gdal_translate $i -a_srs EPSG:4326 -of GTiff ${i%.*}.tif; done
44 | ```
45 | **Entendendo o comando e parâmetros usados**
46 | Como os arquivos asc não possuem o Sistema de Referencia Cartográfica definido, vou aproveitar e definir o SRC para o output, com o comando `-a_srs EPSG:4326` onde 4326 é o id do SRC WGS84. Além disso, defino o formato de outpu com o comando `-of GTiff`.
47 | Para informar o nome do arquivo de output, vou aproveitar a lista criada, mas precisarei remover a extensão *.asc* e inserir a extensão *.tif*. Para tanto, uso o comando `${i%.\*}.tif`
48 |
--------------------------------------------------------------------------------
/python/scripts/sigef_services/add_servicos_sigef.py:
--------------------------------------------------------------------------------
1 | from qgis.PyQt.QtWidgets import QInputDialog, QMessageBox
2 |
3 | base_url = "http://acervofundiario.incra.gov.br/i3geo/ogc.php?tema="
4 | temas = [
5 | "certificada_sigef_particular",
6 | "certificada_sigef_publico",
7 | "imoveiscertificados_privado",
8 | "imoveiscertificados_publico",
9 | "parcelageo",
10 | "assentamentos",
11 | "reconhecimento",
12 | "quilombolas",
13 | ]
14 | # Dicionário de estados brasileiros com siglas em minúsculas
15 | estados_brasileiros = {
16 | "Acre": "ac",
17 | "Alagoas": "al",
18 | "Amapá": "ap",
19 | "Amazonas": "am",
20 | "Bahia": "ba",
21 | "Ceará": "ce",
22 | "Distrito Federal": "df",
23 | "Espírito Santo": "es",
24 | "Goiás": "go",
25 | "Maranhão": "ma",
26 | "Mato Grosso": "mt",
27 | "Mato Grosso do Sul": "ms",
28 | "Minas Gerais": "mg",
29 | "Pará": "pa",
30 | "Paraíba": "pb",
31 | "Paraná": "pr",
32 | "Pernambuco": "pe",
33 | "Piauí": "pi",
34 | "Rio de Janeiro": "rj",
35 | "Rio Grande do Norte": "rn",
36 | "Rio Grande do Sul": "rs",
37 | "Rondônia": "ro",
38 | "Roraima": "rr",
39 | "Santa Catarina": "sc",
40 | "São Paulo": "sp",
41 | "Sergipe": "se",
42 | "Tocantins": "to",
43 | }
44 |
45 | servicos = {"WFS": "connections-wfs", "WMS": "connections-wms"}
46 |
47 | # Lista de nomes dos estados para exibir no QInputDialog
48 | nomes_estados = list(estados_brasileiros.keys())
49 |
50 | # Cria e exibe o QInputDialog para escolha de um estado
51 | estado_escolhido, ok = QInputDialog.getItem(
52 | None, "Escolha um Estado", "Estados:", nomes_estados, 0, False
53 | )
54 |
55 | # Verifica se o usuário pressionou o botão OK e escolheu um estado
56 | if ok and estado_escolhido:
57 | # Obtém a sigla do estado escolhido
58 | servico_escolhido, ok_servico = QInputDialog.getItem(
59 | None, "Escolha o Serviço", "Serviço:", servicos, 0, False
60 | )
61 | servico = None
62 | if ok_servico and servico_escolhido:
63 | # Obtém a sigla do estado escolhido
64 | sigla_estado = estados_brasileiros[estado_escolhido]
65 | # Mensagem final incluindo a escolha do serviço
66 | servico = servicos[servico_escolhido]
67 | else:
68 | QMessageBox.warning(None, "Cancelado", "A escolha do serviço foi cancelada.")
69 | exit()
70 |
71 | urls = []
72 | for tema in temas:
73 | conn_name = f"{tema.replace('_', ' ').title()} {sigla_estado.upper()}"
74 | conn_type = servico
75 | url_tema = f"{base_url}{tema}_{sigla_estado}"
76 |
77 | QSettings().setValue(f"qgis/{conn_type}/{conn_name}/authcfg", "")
78 | QSettings().setValue(f"qgis/{conn_type}/{conn_name}/url", url_tema)
79 | print("Adicionando:", servico, url_tema)
80 | urls.append(url_tema)
81 |
82 | iface.reloadConnections()
83 | sigla_estado = estados_brasileiros[estado_escolhido]
84 | # Mostra uma mensagem com o estado escolhido e sua sigla
85 | mensagem = f"Conexões {servico} do Estado {estado_escolhido} ({sigla_estado.upper()}) adicionadas com suscesso.\n "
86 | mensagem += "\n ".join(urls)
87 |
88 | QMessageBox.information(None, "Dados SIGEF", mensagem)
89 | # Faz o print do estado e sua sigla
90 | else:
91 | QMessageBox.warning(None, "Cancelado", "Nenhuma seleção foi feita.")
92 |
--------------------------------------------------------------------------------
/python/funcoes_qgis/plot_tree.py:
--------------------------------------------------------------------------------
1 | # Created At 2021-09-21
2 | # By Kyle Felipe At gmail.com
3 | # Função cria um ponto em uma linha a partir de uma distância em x e y
4 | # sendo que a distância em x é o deslocamento em relação ao início da linha, em metros
5 | # e a distância em y é o deslocamento perpendicular à linha, em metros
6 | # Qgis => 3.22
7 | # Função foi criada em função da dúvida de um colega no grupo do telegram do Qgis Brasil
8 | # https://t.me/thinkfreeqgis
9 |
10 | from qgis.core import *
11 | from qgis.gui import *
12 |
13 |
14 | @qgsfunction(args='auto', group='Kyle Expressions', referenced_columns=[])
15 | def plot_tree(dist_x,
16 | dist_y,
17 | layer_id,
18 | layer_field,
19 | value,
20 | side, feature, parent):
21 | """
22 | Calcula um ponto a partir de uma distância x do início de linha e uma distancia y
23 | perpendicular à linha.
24 | Parâmetros
25 |
26 |
27 | | dist_x | Distância em x, em metros |
28 |
29 |
30 | | dist_y | Distância em y, em metros |
31 |
32 |
33 | | layer_id | Id da camada de linha |
34 |
35 |
36 | | layer_field | Campo da camada de linha com identificador único |
37 |
38 |
39 | | value | Valor do campo da camada de linha |
40 |
41 |
42 | | side | Lado do ponto em relação à linha. Escolha entre "left" ou "right" |
43 |
44 |
45 | Exemplo de uso:
46 |
47 | - plot_tree( "x" , "y" , 'linhas_cb908956_f5b0_4fc0_aefe_e029d1d62837', 'fid', 1, 'right') -> geometry: Point
48 |
49 | """
50 | # Get the line layer
51 | line_layer = QgsProject.instance().mapLayer(layer_id)
52 | # Create string expression to filter the line layer
53 | expression = f'"{layer_field}" = {value}'
54 | # create a feature request with the expression to filter the line layer
55 | request = QgsFeatureRequest().setFilterExpression(expression)
56 | # get the feature from the line layer
57 | line_feature = line_layer.getFeatures(request)
58 | line_feature = next(line_feature)
59 | # Get the geometry of the line feature
60 | geom_line = line_feature.geometry().asPolyline()
61 | # get the start point of the line
62 | start_point = geom_line[0]
63 | # Get the point at the distance dist_x
64 | interpolated_distance = line_feature.geometry().interpolate(dist_x).asPoint()
65 | # Calculate slope of AB
66 | xA, yA = start_point.x(), start_point.y()
67 | xB, yB = interpolated_distance.x(), interpolated_distance.y()
68 | slope_AB = (yB - yA) / (xB - xA)
69 |
70 | # Calculate slope of BC as negative reciprocal of AB
71 | slope_BC = -1 / slope_AB
72 |
73 | # Calculate x-coordinate of point C using Pythagorean theorem
74 | xC1 = xB + dist_y / (slope_BC ** 2 + 1) ** 0.5
75 | xC2 = xB - dist_y / (slope_BC ** 2 + 1) ** 0.5
76 |
77 | # Select the correct x-coordinate of point C
78 | if side == 'right':
79 | xC = xC1
80 | else:
81 | xC = xC2
82 |
83 | # Calculate y-coordinate of point C using equation of line BC
84 | yC = slope_BC * (xC - xB) + yB
85 |
86 | # Returning a geometry with the point C
87 | return QgsGeometry.fromPointXY(QgsPointXY(xC, yC))
88 |
--------------------------------------------------------------------------------
/docs/Python_postgis.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - DOCS - Postgis documentation
2 |
3 | O script, feito em _Python 3_, importa para um banco de dados Postgis um aquivo CSV para que seja feito o georreferenciamento dos
4 | dados no final do processo.
5 | Dependencias:
6 | * Psycopg: Pacote para Python utilizado para manipular o banco de dados, necessária a verificação da instalação.
7 |
8 | É composto por:
9 | * connect.py: É o arquivo principal, que contém a maior parte do código.
10 | * config.py:
11 | * database.ini
12 |
13 |
14 | ## database.ini
15 |
16 | É um arquivo de configuração utilizado para auxiliar na conexão com o banco, acesso ao csv, a tabela com geometria, criação da tabela que irá receber o CSV e
17 | a criação da tabela virtual com cruzamento das tabelas.
18 | Esses parêmetros podem, e devem ser modificados conforme a necessidade de utilização.
19 |
20 | Possui 3 sessões (sections) listadas a baixo:É o campo da tabela que será uitilizado como chave para fazer a união das tabelas.
21 |
22 | * [postgresql]: Esssa sessão possui as informações de conexo com o banco.
23 | host: Endereço do banco de dados.
24 | port: Porta de acesso ao bd.
25 | database: nome do banco a ser acessado.
26 | user: nome do usuário a ser usado no acesso ao bd.
27 | password: senha de acsso ao banco.
28 |
29 | * [file_csv]: Essa sessão contem os dados referente ao arquivo CSV a ser importado para o banco.
30 | path: o caminho absoluto do arquivo.
31 | delimiter:caractere utilizado como delimitador dos dados dentro do arquivo CSV. Exemplo ; ou ,.
32 | key (remover essa tag)
33 |
34 | * [table_csv]: Contem os parâmetros da tabela que será criada para receber o arquivo CSV.
35 | schema: Nome do Schema onde a tabela será criada.
36 | table: Nome da tabela a ser criada que irá receber os dados do CSV.
37 | key: É o campo da tabela que será uitilizado como chave para fazer a união das tabelas.
38 |
39 | * [join_table]: Contem os parâmetros da tabela do banco que ser utilizada na união para georreferenciar os dados do CSV.
40 | schema: Nome do Schema onde a tabela se encontra.
41 | table: Nome da tabela que será utilizada.
42 | key: É o campo da tabela que será uitilizado como chave para fazer a união das tabelas.
43 | geometry: É o nome do campo da tabela que contém a geometria.
44 |
45 | ## config.py
46 |
47 | Esse aquivo possui a função "config()" que lê o arquivo database.ini e retorna um dicionario de dados das sessões contidas lá dentro, conforme o
48 | código principal vai precisando do dado.
49 | Caso seja solicitado alguma sessão que não está contida nele, ele dispara um erro dizendo que a sessão não foi encontrada.
50 |
51 | A função possui dois parâmetros a serem informados no momento da uilitzação:
52 |
53 | * filename: Aqui é informado o nome do aquivo que possui a ser utilizado.
54 | * section: Nome da sessão que deseja acessar.
55 |
56 |
57 | ## connect.py
58 |
59 | É o arquivo principal, contendo todo os comandos python e SQL utilizados na inserção e cruzamento dos dados.
60 | contem duas variáveis globais e as funções utilizadas:
61 |
62 | * _Variáveis_: armazenam os dados que o arquivo config.py retorna de acordo com a sessão solicitada.
63 |
64 | * open_csv(): Essa função foi feita para ler o CSV e buscar os cabeçalhos na primeira linha e retorna as colunas e um texto
65 | básico com o cabeçalho da tabela a ser criada.
66 |
67 | * connect(): Essa é a função principal, responsável por conectar ao banco de dados e fazer a manipulação do banco, como a criação
68 | da tabela que irá receber os dados do aquivo CSV, insere os dados e faz a união das tabelas.
69 | Cada passo do processo possui um comentãrio relativo, e caso haja alugm erro de execussão nessa função, a criação da e cruzamento das
70 | tabelas não será executada.
71 |
72 | Os códigos podem ser alterados conforme a necessidade de utilização.
73 |
--------------------------------------------------------------------------------
/python/funcoes_qgis/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - PYTHON - funcoes_qgis
2 | Aqui estão contidas as funções que tenho criado para o QGIS.
3 |
4 | Como inserir funções novas no QGIS:
5 | Abra a calculadora de campo do QGIS e clique na aba "EDITOR DE FUNÇÃO"
6 | Clique em "NEW FILE", copie o código da expressão que deseja e cole na janela do QGIS, em seguida clique em LOAD
7 | A função nova irá aparecer na listagem....
8 | Assista ao vídeo de como inserir novas funções, feitas no python, no QGIS:
9 | [](https://www.youtube.com/watch?v=7JEcE0t70-c)
10 |
11 |
12 | Função verifica_valor:
13 | > Recebe uma lista, ou um campo que contenha uma lista, os valores devem possui um separador (virgula, dois pontos, ponto e vírgula, etc), e retorna Verdadeiro ou Falso.
14 | Dependencias: Não há
15 | Lista de funções: "Lista"
16 | Sintaxe: verifica_valor(lista, divisor, dado)
17 | Argumentos:
18 | lista: É a lista, ou campo que conhenha uma lista.
19 | separador: é o simbolo utilizado como separador (vírgula, ponto, dois pontos, ponto e vígula...) entre aspas simples ''.
20 | pesquisa: é o dado que deseja procurar dentro da lista.
21 | Exemplo verifica_valor('1, 2, 3, 4', ',', 1) >> True
22 | OBS: É importante não utilizar letras como separador, bem como espaço e o simbolo _ (underline).
23 |
24 | Função padroniza_data:
25 | > Padroniza uma data em em um campo da tabela de atributos e retorna no formato aaaa-mm-dd, a data a ser modificada
26 | não contiver dia, mes e ano, a função retorna Null.
27 | Dependencias: Não há
28 | Lista de funções: "Date and Time"
29 | Sintaxe: padroniza_data(separador, data)
30 | separador: é o simbolo utilizado como separador (vírgula, ponto, dois pontos, ponto e vígula...) entre aspas simples ''.
31 | data: é o data, ou campo que conten os dados de data.
32 | Exemplo1 padroniza_data('/', '01/jan/2017') >> 2017-01-01
33 | Exemplo2 padroniza_data('/', '01/jan') >> Null
34 | OBS: É importante não utilizar letras como separador, bem como espaço e o simbolo _ (underline).
35 |
36 | Função plot_tree:
37 | > Função cria um ponto em uma linha a partir de uma distância em x e y
38 | > sendo que a distância em x é o deslocamento em relação ao início da linha, em metros
39 | > e a distância em y é o deslocamento perpendicular à linha, em metros
40 | Dependencias: Não há
41 | Lista de funções: "Kyle Expressions"
42 | Sintaxe: plot_tree(dist_x, dist_y, layer_id, layer_field, value, side)
43 | dist_x: É a Distancia em x, em metros, em relação ao início da linha.
44 | dist_y: É a Distancia em y, em metros, perpendicular à linha a apartir do ponto acima
45 | layer_id: É o id da camada que contém a linha
46 | layer_field: É o campo identificador da feição na camada que contém a linha
47 | value: É o valor do campo identificador da feição na camada que contém a linha
48 | side: É o lado da linha onde o ponto será plotado, sendo que 'left' é o lado esquerdo e 'right' é o lado direito
49 | Exemplo: plot_tree('layer', 'tree', 'parent')
50 |
51 | Função polygon_sphericity:
52 | > Calcula o grau de esfericidade de um poligono, fazendo a relação entre o perimetro de um vetor com sua area e retrona um valor entre 0 e 1, sendo que quanto mais proximo a 1 mais circular é a fórma do vetor.
53 | Dependencias: Não Há
54 | Sitnaxe: polygon_sphericity(area, perimeter)
55 | area: É o campo na tabela de atributos que contem o dado de área, ou a função de calculo da área.
56 | perimeter: É o campo na tabela de atributos que contém o dado de área, ou a função de calculo da área.
57 | Exemplo: relate_area_perimeter($area, $perimeter) >>> 0.607763480072298
58 | OBSERVAÇÃO: AMBAS MEDIDAS NECESSITAM ESTAR NA MESMA UNIDADE.
59 |
60 | Função wrap_delimiter:
61 | > Quebra um texto de acordo com um delimitador
62 | Dependencias: Não Há
63 | Sitnaxe: wrap_dellimiter(string, delimiter)
64 | string: Texto a ser quebrado
65 | delimieter: É o caractere onde deve ocorrer a quebra do texto, sempre ente aspas simples.
66 | Exemplo: wrap-delimiter('don't panic, it will be wrapped', ',')
67 | don't panic
68 | it will be wrapped
69 |
70 | Função vertices_to_html:
71 | > Cria uma tabela HTML com os vértices de uma geometria enumerados
72 | Dependências: Não há
73 | Sintaxe: `vertices_to_html(geomety)`
74 | geometry: É a geometria que deseja gerar a tabela.
75 | OBSERVAÇÃO: PYTHON VERSION 3.5 +
76 |
--------------------------------------------------------------------------------
/python/csv2postgis/csv2postgis.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | # -*- coding: utf-8 -*-
3 | # http://www.postgresqltutorial.com/postgresql-python/connect/
4 | # Author: Julio Menezes
5 | # Mod by: Kyle Felipe
6 | # sudo apt-cache search psycopg2
7 | # sudo apt-get install python3-psycopg2
8 |
9 | import psycopg2
10 | import csv
11 | import config
12 |
13 | csv_params = config.config(filename='database.ini', section='file_csv')
14 | table_params = config.config(filename='database.ini', section='table_csv')
15 |
16 |
17 | def open_csv():
18 | """ Open the CSV file"""
19 | with open(file=csv_params["path"], encoding="utf8", mode="r", newline='') as csv_file:
20 | rows = list(csv.reader(csv_file, delimiter=csv_params["delimiter"]))
21 | heading = rows[0]
22 | sql = str.join(" text, ", heading)
23 | # print("ok")
24 | return heading, sql
25 |
26 |
27 | def connect():
28 | """ Connect to the PostgreSQL database server """
29 | conn = None
30 | join_params = config.config(filename='database.ini', section='join_table')
31 | try:
32 | # read connection parameters
33 | params = config.config(filename='database.ini', section='postgresql')
34 |
35 | # connect to the PostgreSQL server
36 | print('Connecting to the PostgreSQL database...')
37 | conn = psycopg2.connect(**params)
38 |
39 | # create a cursor
40 | cur = conn.cursor()
41 |
42 | # execute a statement
43 | print('PostgreSQL database version:')
44 | cur.execute('SELECT PostGIS_Full_Version()')
45 |
46 | # display the PostgreSQL database server version
47 | db_version = cur.fetchone()
48 | print(db_version)
49 | sql_count = """SELECT count(*) from {schema}.{table};""".format(schema=join_params["schema"],
50 | table=join_params["table"])
51 | cur.execute(sql_count)
52 | retorno = cur.fetchone()
53 | print(retorno)
54 |
55 | # Creating tabel acording to database.ini [table] and importing a csv file.
56 |
57 | print("Creating tabel {}...".format(table_params["table"]))
58 | sql_create = ("""CREATE TABLE IF NOT EXISTS {schema}.{table} (id bigserial,
59 | {columns} text);""".format(schema=table_params["schema"], table=table_params["table"], columns=open_csv()[1]))
60 | cur.execute(sql_create)
61 | print(sql_create)
62 |
63 | # Importing data from CSV
64 | print("Importing CSV file...")
65 | sql_copy = (
66 | """COPY {schema}.{table} ({columns}) FROM STDIN
67 | WITH (FORMAT CSV, HEADER, DELIMITER '{delim}');""".format(schema=table_params["schema"],
68 | table=table_params["table"],
69 | columns=str.join(" ,", open_csv()[0]),
70 | delim=csv_params["delimiter"]))
71 | csv_stdin = open(file=csv_params["path"], mode="r", newline='')
72 |
73 | cur.copy_expert(sql=sql_copy, file=csv_stdin)
74 | csv_stdin.close()
75 | print("Import done...\nJoing tables...")
76 |
77 | # Joining tables
78 | sql_join = """CREATE OR REPLACE VIEW {schema}.join_csv_teste AS
79 | SELECT a.id, a.municipio, a.coluna_1, a.coluna_2,b.{geometry}
80 | FROM {table_csv} as a, {join_table} as b
81 | WHERE a.{csv_key}::text = b.{join_key};""".format(schema=join_params["schema"],
82 | geometry=join_params["geometry"],
83 | table_csv=table_params["table"],
84 | join_table=join_params["table"],
85 | csv_key=table_params["key"],
86 | join_key=join_params["key"]
87 | )
88 | cur.execute(sql_join)
89 |
90 | # close the communication with the PostgreSQL
91 | cur.close()
92 | conn.commit()
93 | except (Exception, psycopg2.DatabaseError) as error:
94 | print(error)
95 | finally:
96 | if conn is not None:
97 | conn.close()
98 | print('Database connection closed.')
99 |
100 |
101 | if __name__ == '__main__':
102 | connect()
103 |
--------------------------------------------------------------------------------
/python/csv2postgis/README.md:
--------------------------------------------------------------------------------
1 | # QGIS, tips & tricks - PYTHON - csv2postgis
2 |
3 | O script surgiu de uma necessidade de um colega no grupo do [Telegram](https://telegram.org) ThinkFree - Qgis.
4 | A intenção é, utilizando __Python 3__, inserir os dados de um aruivo CSV em um banco de dados [POSTGIS](https://postgis.net/) e,
5 | em seguida, fazer a união desses dados a uma tabela que já contenha geometria definida, georreferenciando os dados do CSV.
6 |
7 | A tabela utilizada para fazer o georreferenciamento dos dados do CSV foi o do Limite Municipal de MG (IBGE).
8 |
9 | __ATENÇÃO:__ É necessário a instalação do [psycopg](http://initd.org/psycopg/docs/index.html) no Python antes de utilizar.
10 |
11 | É composto por:
12 |
13 | * [config.py](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/python/csv2postgis/config.py): Código de busca a configuração dos dados para o [csv2postgis.py](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/python/csv2postgis/csv2postgis.py)..
14 | * [csv2postgis.py](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/python/csv2postgis/csv2postgis.py): Script de inserção do CSV e cruzamento das tabelas.
15 | * [database.ini](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/python/csv2postgis/database.ini): Arquivo contendo os paramentos de conexão com o bd Postgis, do CSV e da tabela que será usada no georreferenciamento dos dados.
16 | * [arquivo.csv](https://github.com/kylefelipe/qgis-tips-tricks/blob/master/python/csv2postgis/arquivo.csv): Aquivo utilizado no exemplo.
17 |
18 |
19 | ## database.ini
20 |
21 | É um arquivo de configuração utilizado para auxiliar na conexão com o banco, acesso ao csv, a tabela com geometria, criação da tabela que irá receber o CSV e
22 | a criação da tabela virtual com cruzamento das tabelas.
23 | Esses parêmetros podem, e devem ser modificados conforme a necessidade de utilização.
24 |
25 | Possui 3 sessões (sections) listadas a baixo:É o campo da tabela que será uitilizado como chave para fazer a união das tabelas.
26 |
27 | * [postgresql]: Esssa sessão possui as informações de conexo com o banco.
28 | host: Endereço do banco de dados.
29 | port: Porta de acesso ao bd.
30 | database: nome do banco a ser acessado.
31 | user: nome do usuário a ser usado no acesso ao bd.
32 | password: senha de acsso ao banco.
33 |
34 | * [file_csv]: Essa sessão contem os dados referente ao arquivo CSV a ser importado para o banco.
35 | path: o caminho absoluto do arquivo.
36 | delimiter:caractere utilizado como delimitador dos dados dentro do arquivo CSV. Exemplo ; ou ,.
37 | key (remover essa tag)
38 |
39 | * [table_csv]: Contem os parâmetros da tabela que será criada para receber o arquivo CSV.
40 | schema: Nome do Schema onde a tabela será criada.
41 | table: Nome da tabela a ser criada que irá receber os dados do CSV.
42 | key: É o campo da tabela que será uitilizado como chave para fazer a união das tabelas.
43 |
44 | * [join_table]: Contem os parâmetros da tabela do banco que ser utilizada na união para georreferenciar os dados do CSV.
45 | schema: Nome do Schema onde a tabela se encontra.
46 | table: Nome da tabela que será utilizada.
47 | key: É o campo da tabela que será uitilizado como chave para fazer a união das tabelas.
48 | geometry: É o nome do campo da tabela que contém a geometria.
49 |
50 | ## config.py
51 |
52 | Esse aquivo possui a função "config()" que lê o arquivo database.ini e retorna um dicionario de dados das sessões contidas lá dentro, conforme o
53 | código principal vai precisando do dado.
54 | Caso seja solicitado alguma sessão que não está contida nele, ele dispara um erro dizendo que a sessão não foi encontrada.
55 |
56 | A função possui dois parâmetros a serem informados no momento da uilitzação:
57 |
58 | * filename: Aqui é informado o nome do aquivo que possui a ser utilizado.
59 | * section: Nome da sessão que deseja acessar.
60 |
61 |
62 | ## csv2postgis.py
63 |
64 | É o arquivo principal, contendo todo os comandos python e SQL utilizados na inserção e cruzamento dos dados.
65 | contem duas variáveis globais e as funções utilizadas:
66 |
67 | * _Variáveis_: armazenam os dados que o arquivo config.py retorna de acordo com a sessão solicitada.
68 |
69 | * open_csv(): Essa função foi feita para ler o CSV e buscar os cabeçalhos na primeira linha e retorna as colunas e um texto
70 | básico com o cabeçalho da tabela a ser criada.
71 |
72 | * connect(): Essa é a função principal, responsável por conectar ao banco de dados e fazer a manipulação do banco, como a criação
73 | da tabela que irá receber os dados do aquivo CSV, insere os dados e faz a união das tabelas.
74 | Cada passo do processo possui um comentãrio relativo, e caso haja alugm erro de execussão nessa função, a criação da e cruzamento das
75 | tabelas não será executada.
76 |
77 | Os códigos podem ser alterados conforme a necessidade de utilização.
78 |
--------------------------------------------------------------------------------
/python/processing_scripts/generate_label/generate_label.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | ***************************************************************************
5 | * *
6 | * This program is free software; you can redistribute it and/or modify *
7 | * it under the terms of the GNU General Public License as published by *
8 | * the Free Software Foundation; either version 2 of the License, or *
9 | * (at your option) any later version. *
10 | * *
11 | ***************************************************************************
12 | """
13 |
14 | from qgis.PyQt.QtCore import (QCoreApplication, QVariant)
15 | from qgis.core import (QgsProcessing,
16 | QgsFeatureSink,
17 | QgsProcessingException,
18 | QgsProcessingAlgorithm,
19 | QgsProcessingParameterFeatureSource,
20 | QgsProcessingParameterCrs,
21 | QgsProcessingParameterString,
22 | QgsProcessingParameterBoolean,
23 | QgsProcessingParameterFeatureSink,
24 | QgsFeatureRequest,
25 | QgsExpression,
26 | QgsField,
27 | QgsFeature,
28 | )
29 | from qgis import processing
30 |
31 |
32 | class GenerateLabel(QgsProcessingAlgorithm):
33 | """
34 | Generating Label ordered by geometry area
35 | """
36 |
37 | # Constants used to refer to parameters and outputs. They will be
38 | # used when calling the algorithm from another algorithm, or when
39 | # calling from the QGIS console.
40 |
41 | INPUT = 'INPUT'
42 | OUTPUT = 'OUTPUT'
43 | FIELD_NAME = 'FIELD_NAME'
44 | CRS_ID = 'CRS_ID'
45 | ASC_DESC = 'ASC_DESC'
46 | LABEL_PREFIX = 'LABEL_PREFIX'
47 | LABEL_SUFIX = 'LABEL_SUFIX'
48 | NEW_POSITION = 'new_position'
49 |
50 | def tr(self, string):
51 | """
52 | Returns a translatable string with the self.tr() function.
53 | """
54 | return QCoreApplication.translate('Processing', string)
55 |
56 | def createInstance(self):
57 | return GenerateLabel()
58 |
59 | def name(self):
60 | """
61 | Returns the algorithm name, used for identifying the algorithm. This
62 | string should be fixed for the algorithm, and must not be localised.
63 | The name should be unique within each provider. Names should contain
64 | lowercase alphanumeric characters only and no spaces or other
65 | formatting characters.
66 | """
67 | return 'generatelabel'
68 |
69 | def displayName(self):
70 | """
71 | Returns the translated algorithm name, which should be used for any
72 | user-visible display of the algorithm name.
73 | """
74 | return self.tr('Generate Label')
75 |
76 | def group(self):
77 | """
78 | Returns the name of the group this algorithm belongs to. This string
79 | should be localised.
80 | """
81 | return self.tr('Kyle scripts')
82 |
83 | def groupId(self):
84 | """
85 | Returns the unique ID of the group this algorithm belongs to. This
86 | string should be fixed for the algorithm, and must not be localised.
87 | The group id should be unique within each provider. Group id should
88 | contain lowercase alphanumeric characters only and no spaces or other
89 | formatting characters.
90 | """
91 | return 'kylescripts'
92 |
93 | def shortHelpString(self):
94 | """
95 | Returns a localised short helper string for the algorithm. This string
96 | should provide a basic description about what the algorithm does and the
97 | parameters and outputs associated with it..
98 | """
99 | short_help = """Este algorìtimo gera um novo campo LABEL no seguite formato
100 | PREFIXO ORDEM DA FEIÇÃO SUFIXO.
101 | As feições são ordenadas de acordo com a area, sendo por padrão em ordem ASCENDENTE.
102 | o SRC de padrão para calculo da área é o 31983
103 | """
104 | return self.tr(short_help)
105 |
106 | def initAlgorithm(self, config=None):
107 | """
108 | Here we define the inputs and output of the algorithm, along
109 | with some other properties.
110 | """
111 |
112 | # We add the input vector features source. It can have polygons only.
113 | self.addParameter(
114 | QgsProcessingParameterFeatureSource(
115 | self.INPUT,
116 | self.tr('Input layer'),
117 | [QgsProcessing.TypeVectorPolygon]
118 | )
119 | )
120 |
121 | # Adds an input to set the new field name
122 | self.addParameter(
123 | QgsProcessingParameterString(
124 | self.FIELD_NAME,
125 | self.tr('Field name'),
126 | 'new_label'
127 | )
128 | )
129 |
130 |
131 | # Adds an input to set the label prefix
132 | self.addParameter(
133 | QgsProcessingParameterString(
134 | self.LABEL_PREFIX,
135 | self.tr('Label Prefix'),
136 | 'A - '
137 | )
138 | )
139 |
140 | # Adds an input to set the label sufix
141 | self.addParameter(
142 | QgsProcessingParameterString(
143 | self.LABEL_SUFIX,
144 | self.tr('Label SUFIX'),
145 | '',
146 | optional=True
147 | )
148 | )
149 | # Adds an input to set the new field
150 | self.addParameter(
151 | QgsProcessingParameterBoolean(
152 | self.ASC_DESC,
153 | self.tr('Ascending'),
154 | True
155 | )
156 | )
157 |
158 |
159 | # Adds an input to set the new field
160 | self.addParameter(
161 | QgsProcessingParameterCrs(
162 | self.CRS_ID,
163 | self.tr('Choose CRS'),
164 | 'EPSG:31983',
165 | )
166 | )
167 | # We add a feature sink in which to store our processed features (this
168 | # usually takes the form of a newly created vector layer when the
169 | # algorithm is run in QGIS).
170 | self.addParameter(
171 | QgsProcessingParameterFeatureSink(
172 | self.OUTPUT,
173 | self.tr('Output layer')
174 | )
175 | )
176 |
177 | def processAlgorithm(self, parameters, context, feedback):
178 | """
179 | Here is where the processing itself takes place.
180 | """
181 |
182 | # Retrieve the feature source and sink. The 'dest_id' variable is used
183 | # to uniquely identify the feature sink, and must be included in the
184 | # dictionary returned by the processAlgorithm function.
185 | source = self.parameterAsSource(
186 | parameters,
187 | self.INPUT,
188 | context
189 | )
190 |
191 |
192 | # If source was not found, throw an exception to indicate that the algorithm
193 | # encountered a fatal error. The exception text can be any string, but in this
194 | # case we use the pre-built invalidSourceError method to return a standard
195 | # helper text for when a source cannot be evaluated
196 | if source is None:
197 | raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
198 |
199 | sink_fields = source.fields()
200 | sink_fields.append(QgsField(self.NEW_POSITION, QVariant.Int))
201 | sink_fields.append(QgsField(parameters['FIELD_NAME'], QVariant.String))
202 |
203 | (sink, dest_id) = self.parameterAsSink(
204 | parameters,
205 | self.OUTPUT,
206 | context,
207 | sink_fields,
208 | source.wkbType(),
209 | source.sourceCrs()
210 | )
211 |
212 | # Send some information to the user
213 | feedback.pushInfo('New field name: {}'.format(parameters['FIELD_NAME']))
214 | feedback.pushInfo('OUTPUT CRS {}'.format(source.sourceCrs().authid()))
215 | feedback.pushInfo('AREA CRS is {}'.format(parameters['CRS_ID'].authid()))
216 | # If sink was not created, throw an exception to indicate that the algorithm
217 | # encountered a fatal error. The exception text can be any string, but in this
218 | # case we use the pre-built invalidSinkError method to return a standard
219 | # helper text for when a sink cannot be evaluated
220 | if sink is None:
221 | raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
222 |
223 | # Compute the number of steps to display within the progress bar and
224 | # get features from source
225 | feature_count = source.featureCount() or 0
226 | total = 100.0 / feature_count if source.featureCount() else 0
227 |
228 | # Ordering by area
229 | request = QgsFeatureRequest()
230 | exp_string = f"area(transform( $geometry, '{source.sourceCrs().authid()}', '{parameters['CRS_ID'].authid()}'))"
231 | exp = QgsExpression(exp_string)
232 | clause = QgsFeatureRequest.OrderByClause(exp, ascending=parameters['ASC_DESC'])
233 | orderby = QgsFeatureRequest.OrderBy([clause])
234 | request.setOrderBy(orderby)
235 | features = source.getFeatures(request)
236 |
237 | for current, feature in enumerate(features):
238 | # Stop the algorithm if cancel button has been clicked
239 | if feedback.isCanceled():
240 | break
241 | new_feature = QgsFeature(sink_fields)
242 | for f in source.fields():
243 | new_feature.setAttribute(f.name(), feature[f.name()])
244 |
245 | new_feature.setGeometry(feature.geometry())
246 |
247 | # Add a feature in the sink
248 | feat_position = f"{current}".zfill(len(str(feature_count)))
249 | new_feature.setAttribute(self.NEW_POSITION, current)
250 | new_feature.setAttribute(parameters['FIELD_NAME'], f"{parameters[self.LABEL_PREFIX]}{feat_position}{parameters[self.LABEL_SUFIX]}")
251 |
252 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert)
253 |
254 | # Update the progress bar
255 | feedback.setProgress(int(current * total))
256 |
257 |
258 |
259 | # Return the results of the algorithm. In this case our only result is
260 | # the feature sink which contains the processed features, but some
261 | # algorithms may return multiple feature sinks, calculated numeric
262 | # statistics, etc. These should all be included in the returned
263 | # dictionary, with keys matching the feature corresponding parameter
264 | # or output names.
265 | return {self.OUTPUT: dest_id}
266 |
--------------------------------------------------------------------------------