├── 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 | 17 | """ 18 | list_vertices = [''] 19 | vertices = feat_geom.vertices() 20 | for id, vertice in enumerate(vertices): 21 | list_vertices.append ((f'' )) 22 | list_vertices.append('
Vértice X Y
{id} {vertice.x()} {vertice.y ()}
') 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 | [![Assista ao vídeo dPython + Qgis = Mais tempo na Vida](https://img.youtube.com/vi/0kaYuPeM0wI/0.jpg)](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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
dist_xDistância em x, em metros
dist_yDistância em y, em metros
layer_idId da camada de linha
layer_fieldCampo da camada de linha com identificador único
valueValor do campo da camada de linha
sideLado do ponto em relação à linha. Escolha entre "left" ou "right"
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 | [![Assista ao vídeo de como inserir novas funções no QGIS](https://img.youtube.com/vi/7JEcE0t70-c/0.jpg)](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 | --------------------------------------------------------------------------------