Norma Cartográfica no QGIS – Alterar formulários de edição com PyQGIS

PT | EN

Enquanto preparava um projecto QGIS para leitura da estrutura de base de dados descrita nas novas Normas e Especificações Técnicas de Cartografia , comecei a configurar os formulários de edição das várias camadas de forma a:

  1. Bloquear a edição de campos só de leitura, como por exemplo um identificador.
  2. Configurar widgets adequados aos campos, que facilitem a vida do utilizador e evitem que cometa erros, como por exemplo campos com dadas e listas de valores fixos.

No fundo, o que procurava era qualquer coisa deste género:

Peek 2019-09-30 15-04_2

Antes de mais, é preciso dizer que o QGIS, quando lê uma tabela PostGreSQL/PostGIS, já faz um excelente trabalho a adivinhar, para cada campo, o tipo de widget a usar, assim  como as constraints a aplicar. O que é uma enorme ajuda. No entanto, alguns campos precisam de uma configuração extra.

Se se tratassem de meia-dúzia de camadas e campos, teria feito tudo de manualmente, mas ao fim da quinta camada, o meu Mantra começou a chamar por mim:

“Quando usas um computador, se estás a fazer manualmente uma tarefa repetitiva, estás a fazê-la mal!”

Então, comecei a pensar como poderia fazer esta configuração de forma mais sistemática para todas as camadas e campos, sem me causar tendinites. Depois de alguma pesquisa, cheguei às funções PyQGIS que apresento a seguir.

Tornar um campo apenas  de leitura

O campo identificador é gerado automaticamente pela base de dados, pelo que o utilizador não só não precisa de o editar, como não deve. Por essa razão, convém tornar o campo não editável.

Layer Properties - cabo_electrico | Attributes Form_103

Para o fazer programaticamente recorri ao seguinte código.

def field_readonly(layer, fieldname, option = True):
    fields = layer.fields()
    field_idx = fields.indexOf(fieldname)
    if field_idx >= 0:
        form_config = layer.editFormConfig()
        form_config.setReadOnly(field_idx, option)
        layer.setEditFormConfig(form_config)

# Exemplo para o campo "identificador"

project = QgsProject.instance()
layers = project.mapLayers() 

for layer in layers.values():
    field_readonly(layer,'identificador')

Configurar um campo com o widget DateTime

Os campos de datas ficam configurados automaticamente, mas o widget usado por omissão, ao contrário do que é exigido pela norma, apenas guarda a data e não a data e  hora.

Comecei por configurar como queria um campo de exemplo e depois fui ver como a configuração era gravada em PyQGIS usando a consola python:

>>>layer = iface.mapCanvas().currentLayer()
>>>layer.fields().indexOf('inicio_objeto')
1
>>>field = layer.fields()[1]
>>>field.editorWidgetSetup().type()
'DateTime'
>>>field.editorWidgetSetup().config()
{'allow_null': True, 'calendar_popup': True, 'display_format': 'yyyy-MM-dd HH:mm:ss', 'field_format': 'yyyy-MM-dd HH:mm:ss', 'field_iso_format': False}

Com isso consegui criar uma função que me permitisse configurar qualquer campo com a mesma configuração:

def field_to_datetime(layer, fieldname):
    config = {'allow_null': True,
              'calendar_popup': True,
              'display_format': 'yyyy-MM-dd HH:mm:ss',
              'field_format': 'yyyy-MM-dd HH:mm:ss',
              'field_iso_format': False}
    type = 'Datetime'
    fields = layer.fields()
    field_idx = fields.indexOf(fieldname)
    if field_idx >= 0:
        widget_setup = QgsEditorWidgetSetup(type,config)
        layer.setEditorWidgetSetup(field_idx, widget_setup)

# Exemplo para os campos "inicio_objeto" e "fim_objeto"

for layer in layers.values():
    field_to_datetime(layer,'inicio_objeto')
    field_to_datetime(layer,'fim_objeto')

Configurar um campo com o widget Value Relation

No modelo de dados, muitas tabelas contém campos que apenas aceitam um conjunto finito de valores. Valores estes que são listados noutra tabela, os chamados Foreign keys.

Para estes casos, é conveniente no QGIS configurar um widget de relação de tabela. Para o fazer de forma programática, o processo é identico ao mostrado anteriormente, em que há que descobrir primeiro o tipo e a configuração de uma campo já preparado. Mas neste caso, cada campo terá uma configuração ligeiramente diferente.

Felizmente, quem desenhou a estrutura de dados facilitou-nos a vida ao dar o mesmo nome aos campos e às tabela de valores associada, e todos eles começados com a texto “valor_”, tornando possivel que também essa parte seja automática.

A funçao abaixo começa por identificar para determinada camada todos os campos cujo nome começa por “valor_”. Depois iterando sobre os campos encontrados, adapta a configuração de forma a usar como camada de referência (‘Layer’) a camada com o mesmo nome que o campo.

def field_to_value_relation(layer):
    fields = layer.fields()
    pattern = re.compile(r'^valor_')
    fields_valor = [field for field in fields if pattern.match(field.name())]
    if len(fields_valor) > 0:
        config = {'AllowMulti': False,
                  'AllowNull': True,
                  'FilterExpression': '',
                  'Key': 'identificador',
                  'Layer': '',
                  'NofColumns': 1,
                  'OrderByValue': False,
                  'UseCompleter': False,
                   'Value': 'descricao'}
        for field in fields_valor:
            field_idx = fields.indexOf(field.name())
            if field_idx >= 0:
                print(field)
                try:
                    target_layer = QgsProject.instance().mapLayersByName(field.name())[0]
                    config['Layer'] = target_layer.id()
                    widget_setup = QgsEditorWidgetSetup('ValueRelation',config)
                    layer.setEditorWidgetSetup(field_idx, widget_setup)
                except:
                    pass
            else:
                return False
    else:
        return False
    return True
    
# Correr função em todas as camadas
for layer in layers.values():
    field_to_value_relation(layer)

Conclusão

Assim, de forma relativamente rápida, consegui configurar todas as camadas do projecto com os widgets que queria.

Peek 2019-09-30 16-06

Esta é a ponta do iceberg. Havendo necessidade, com um pouco de paciência e pesquisa, outras configurações podem ser alteradas usando PyQGIS. Por isso, pense nisso antes de começar a configurar camada a camada, campo a campo.

Advertisement

Saudades do QGIS (enquanto uso ArcGIS)

(aka Funcionalidades que os utilizadores de ArcGIS Desktop nem sonham que existem)

EN | PT

De tempos a tempos, leio artigos de comparação entre o ArcGIS e o QGIS. Uma vez que partem geralmente do ponto de vista de utilizadores de ArcGIS, acabam invariavelmente em observações parciais sobre a falta de funcionalidades do QGIS. Está na hora de mudar o ponto de vista. Por isso, convido-vos a acompanharem-me neste artigo (um pouco) longo, totalmente e assumidamente parcial.

“Olá, o meu nome é Alexandre, e tenho usado… QGIS

Eis algo que eu diria numa sessão de terapia em grupo dos Utilizadores Anónimos do QGIS. Estou a precisar de ir a uma sessão dessas porque, tendo sido recentemente forçado a voltar a usar – de forma temporária – o ArcGIS, sinto muita muita muita falta do QGIS em vários aspectos.

Em tempos idos, houve alturas em que usava o ArcGIS diariamente. Usei-o até à versão 9.3.1, até que me decidi a mudar para o QGIS (versão 1.7.4, acho eu). Na altura, senti falta de algumas (muitas?) funcionalidades do ArcGIS, mas estava disposto a trocá-las pela liberdade oferecida pela filosofia Open Source. Desde essa altura, passou-se muita coisa no universo QGIS, e eu tenho-me mantido avidamente atento à sua evolução. Esperaria que o mesmo tivesse acontecido no lado do ArcGIS Desktop, mas, ao que me parece, isso não aconteceu.

Estou a utilizar o topo de gama da ESRI, o ArcGIS 10.3, licença advanced, e debato-me para conseguir fazer pequenas coisas que são simplesmente inexistentes em ArcGIS.  Assim, o que se segue é uma lista de funcionalidades do QGIS das quais sinto falta.

Aviso: Para aqueles que usam exclusivamente o ArcGIS, algumas destas funcionalidades podem apanhá-los de surpresa.

Controlo de transparência

“O ArcGIS tem transparência! Está no separador Display, nas propriedades da camada!”

Sim, é verdade, mas… apenas é possível configurar transparência ao nível da camada. Ou seja, ou é tudo transparente, ou não é nada…

No QGIS, é possível determinar a transparência ao nível da camada, ao nível do  elemento/símbolo, e ao nível da cor. Podem achar que estou a sobrevalorizar o assunto, mas vejam a diferença nas imagens abaixo.

Transparencia_camadaTransparencia_elementoTransparencia_cor

Reparem que no QGIS é possível controlar a transparência sempre (ou quase sempre) que se define uma cor. Isto inclui em anotações (como as usadas nas imagens acima), em etiquetas, e em itens do compositor de impressão. É até possível determinar a transparência de uma cor usando a função RGBA() numa expressão! Que mais se pode pedir? 🙂

Screenshot from 2016-01-27 14:12:34

Modos de Blending

Esta funcionalidade é uma das preciosidades do QGIS, a possibilidade de combinar camadas como faríamos na maioria dos software de edição de imagem. Ao nível da camada e/ou elemento, é possível controlar como o mesmo irá interagir com os elementos e camadas abaixo. Para além do modo normal, estão disponíveis mais 12 modos: Lighen, Screen, Dodge, Darken, Multiply, Burn, Overlay, Soft light, Hard light, Difference and Subtract. Não me vou alongar sobre as propriedade de cada um. Vejam esta página para se informarem acerca da matemática por detrás de cada um deles e alguns exemplos.

Sem se experimentar um pouco, não é fácil perceber em que é que esta funcionalidade nos pode ser útil à produção cartográfica. Eu tive a oportunidade de o fazer enquanto tentava responder a esta pergunta.

2wph4

Uma das mais comuns utilizações para o blending é quando queremos realçar ou simular o relevo adicionando um hillshade por cima das restantes camadas. Em ArcGIS, apenas é possível controlar a transparência da camada, e o resultado final fica sempre um pouco esbatido em relação ao original. Mas no QGIS, é possível manter a força das cores originais usando o modo multiply na camada do hillshade.

Screenshot from 2016-01-27 15:24:38
Hipsometria com as cores originais
Screenshot from 2016-01-27 15:25:45
Cores da hipsometria esbatidas pelo hillshade transparente
Screenshot from 2016-01-27 15:24:45
Cores originais da hipsometria com o hillshade usando o multiply do QGIS

É também possível usar os modos de blending em elementos do compositor de mapas, permitindo combiná-los com outros elementos e texturas. Isto dá-nos a oportunidade de obter resultados mais “artísticos” sem a necessidade de pós-processamento num software de edição de imagem.

Configuração de cores

O eficiente controlo das cores é algo essencial para um cartógrafo, e o QGIS permite-nos controlá-las como profissionais que somos. É possível escolher as cores usando diferentes menus. Menus que poderá reconhecer de software como o Inkscape, Photoshop, Gimp, etc…

O meu favorito é o color picker. Ora vejam, usando o color picker, é possível recolhermos cores de qualquer sítio do nosso ecrã, fora ou dentro do QGIS. Algo muito útil e produtivo quando queremos usar uma cor já existente no nosso mapa, da legenda, de uma palete do  COLOURlovers ou do logo de uma empresa.

anim
Recollhendo uma cor fora do QGIS

Também podemos fazer copy/paste de cores entre menus, gravar e importar paletes de cores e até dar nome a uma cor e usá-la numa variável. Com tudo isto disponível, é-me difícil engolir o menu de selecção de cores do Windows. 😦

 

Modos “avançados” de simbologia de vectores

No ArcGIS, existem várias maneiras de simbolizar as camadas de vectores. Temos Single symbol, Unique values, Unique values many fields… e por aí fora. À primeira impressão, pode até parecer que ao QGIS faltam alguns destes modos, mas acreditem em mim, não faltam! Na verdade, o QGIS oferece muito mais flexibilidade no que toca a simbolizar as suas camadas.

Para começar, pode-se usar tanto ‘campos’ como ‘expressões’ em qualquer um dos modos de simbologia, enquanto que no ArcGIS apenas é possível usar ‘campos’. Alimentado por centenas de funções e com a possibilidade de criarmos as nossas próprias funções usando Python, o que é possível conseguir-se com expressões não tem limites. Torna-se possível seleccionar, recalcular, normalizar (etc…) um número infinito de campos para criar os nossos próprios “valores” (sem falar de que é possível aprimorar as etiquetas associadas aos valores para criar a legenda ideal).

Screenshot from 2016-01-20 22:34:54
Símbolos graduados no QGIS usando uma expressão para calcular a densidade populacional

E depois, no QGIS existem alguns modos “especiais” (e de certa forma bastante específicos) de simbologia, que nos fazem exclamar “wooooh”. Como, por exemplo, os polígonos invertidos, que permitem preencher o exterior dos polígonos (bom para mascarar outros elementos, os pontos desfasados, para mostrar pontos fisicamente demasiado próximos para serem representados, e o Heatmap que transforma qualquer camada de pontos num heatmap sem necessidade de conversão para raster e que é automaticamente actualizado sempre que editamos a camada de pontos.

Screenshot from 2016-01-20 22:58:44
Polígonos invertidos a mascarar o exterior de uma área de interesse

Mas deixei o melhor para o fim. O “One Renderer to rule them all“, a simbologia baseada em regras. Com este modo, é possível adicionar várias regras, agrupá-las numa estrutura de árvore, e atribuir-lhes um símbolo distinto. Cada elemento irá ser representado consoante cumpre ou não cada uma das regras. Isto dá aos utilizadores de QGIS controlo absoluto sobre a simbologia das suas camadas e que, em conjunto com o editor de expressões e as data-defined properties, abre a porta às mais diversas aplicações (veja alguns exemplos na secção abaixo).

rulesymbol_ng_line
Simbologia por regras

Atlas

Uma das minhas funcionalidade favoritas do QGIS é o Atlas do compositor de impressão. Eu sei que o ArcGIS tem o seu próprio “Atlas”, as Data Driven Pages, mas sinceramente, não é a mesma coisa.

Penso que conhecem o funcionamento básico destas ferramentas em ambos os softwares. Cria-se um layout de um mapa, escolhe-se uma camada de vectores como coverage e software irá criar um mapa, devidamente centrado e/ou aproximado para cada elemento da camada. É também possível adicionar etiquetas que irão mudar de acordo com os valores guardados nos atributos da camada.

Mas no QGIS as funcionalidades vão um pouco mais além…

Basicamente, podemos usar os atributos e geometria dos elementos da camada onde quer que seja possível usar uma expressão e, no QGIS, as expressões estão por todo o lado. Desta forma, a maioria das propriedades tanto de camadas, como dos elementos do mapa podem ser controlados pela camada usada no atlas.

Com a devida configuração, iterando por todos os elementos da camada de atlas, é possível escolher os elementos de outras camadas a mostrar ou a esconder, alterar a cor de base do seu mapa, rodar e redimensionar as páginas de acordo com as dimensões do elemento, escolher um logo específico para acompanhar cada mapa, e por aí fora. Mais uma vez, o céu é o limite.

mosaico_regioes_fixed
Série de mapas cuja dimensão foi automaticamente alterada para cobrir os elementos a uma escala fixa

Por isso, se se aliar a funcionalidade de Atlas com as data-defined properties, a simbologia por regras e as expressões, não me parece que o Data Driven Pages do ArcGIS seja um rival à altura. Discordam? Então tentem responder a esta questão.

Dica: Se realmente quiserem levar a produção de cartografia a outro nível de automatismo, usando bases de dados como Spatialite ou Postgis, é possível criar camadas de coverage adequadas para as vossas necessidades através de views. Acaba-se a redundância e a camada estará sempre actualizada.

Menus de estilo e etiquetas

Este é um caso mais de experiência do utilizador (UX) do que propriamente uma funcionalidade em falta, mas não imaginam como é confortável ter todas as opções das etiquetas e dos estilos em apenas um par de janelas (com vários separadores, claro).

Quando uso as opções de simbologia do ArcGIS parece que estou no filme “A origem (Inception)“, às tantas, já nem sei onde estou! Por exemplo, para adicionar um rebordo tracejado a um símbolo de uma camda de polígonos, é preciso abrir 5 janelas diferentes, e depois voltar para trás a clicar OK, OK, OK…

Capture
Opções de símbolos do ArcGIS

No QGIS, uma vez aberta a janela de propriedades da camada, todas as opções estão a um clique de distância (ou quase). E basta carregar em OK ou Aplicar uma vez para visualizar o resultado!

Screenshot from 2016-01-20 21:51:33
Opções de estilos do QGIS

Como bónus, é possível fazer copy/paste de uma camada para a outra, tornando a configuração do estilo de várias camadas muito mais rápida. Ao que me respondem:

“Não sejas ridículo! O ArcGIS também permite importar símbolos de outras camadas.”

Símbolos? Sim. Etiquetas? Não! E se, como eu, perdem algum tempo a configurar de forma primorosa as etiquetas de uma camada, ter de fazer o mesmo ou semelhante para outras camadas, vai-vos dar vontade de chorar… A mim dá.

(Vou deixar a comparação de múltiplos estilos por camada do QGIS vs Data Frames do ArcGIS para outra altura)

WFS

“O quê?!!”

Yup, é isso mesmo, o ArcGIS não suporta o standard OGC WFS a não ser que se compre uma extensão extra: A Extensão de Data Interoperability.

Com o universo SIG (e não só) a evoluir cada vez mais para Dados Abertos, Normas Abertas e Serviços Web OGC, esta situação revela uma posição extremamente mercantil por parte da ESRI. Se fosse um cliente ESRI, sentir-me-ia aldrabado. <sarcasmo> Ou talvez não… talvez me sentisse grato por mais uma oportunidade de investir algum dinheiro nas suas funcionalidades avançadas…<\sarcasmo>

No QGIS, como tudo o resto, o uso do WFS é livre. Tudo o que é preciso é adicionar um URL para o servidor WFS, e podemos começar a adicionar as camadas disponibilizadas, com a certeza de que estarão devidamente actualizadas pela entidade responsável pelo serviço.

Screenshot from 2016-01-20 21:58:54

Felizmente, para os utilizadores ArcGIS menos afortunados, existe sempre a “cómoda” possibilidade de fazerem o download das camadas através do browser de internet :-P.

http://giswebservices.massgis.state.ma.us/geoserver/wfs?request=GetFeature&service=wfs&version=1.0.0&typename=massgis:GISDATA.TOWNS_POLY&outputformat=SHAPE-ZIP

Ou então podem sempre usar o QGIS (ou outro open soure qualquer) para fazer o download. Mas não se esqueçam que as camadas não se irão actualizar sozinhas.

Editor de expressões

Já fiz menção às expressões várias vezes, mas para aqueles que desconhecem o editor de expressões, decidi terminar este artigo com umas das minhas funcionalidades favoritas.

Não conheço o suficiente do editor de expressões do ArcGIS para o poder criticar. Tanto quando percebo, podemos usá-lo para criar labels e para preencher um campo usando o field calculator. Sei que existem certamente muitas funções que podemos usar (apenas utilizei algumas) mas não são visíveis ao utilizador comum. Provavelmente é preciso consultar a documentação de ajuda para conhecê-las todas. É ainda possível criar funções em VBScript, Python e JsScript.

Capture

No QGIS, como já referi, podem-se usar expressões praticamente em todo o lado, o que é bastante conveniente para muitas aplicações. No que toca a funções, existem centenas disponíveis directamente na janela do editor de expressões, todas devidamente acompanhadas por informação sobre a sua sintaxe e alguns exemplos ilustrativos. Também se podem usar campos e valores como no ArcGIS, e até existe uma secção de “expressões recentes” para quando precisamos de reutilizar uma expressão.

Capture

Para além disso, também é possível criar as nossas próprias funções em Python (nada de VBScript ou JsScript), mas desta feita num editor próprio, num outro separador. Um editor equipado com autocomplete e code highlight para nos facilitar a vida, e que permite gravar as funções no ambiente do utilizador para serem usadas posteriormente (inclusive noutras sessões de QGIS).

Capture

Conclusão

Estas não são certamente as únicas funcionalidades do QGIS de que sinto falta, e não serão certamente as mais limitantes (por exemplo, não poder usar em pleno bases de dados Spatialite e Postgis vai, de certeza, tornar-me a vida num inferno nos próximos tempos), mas são aquelas que identifiquei assim que (re)abri o ArcGIS pelas primeiras vezes.

Para além disso, sinto que, com a  actual dinâmica de desenvolvimento do QGIS, a cada nova versão, esta lista irá crescer muito rapidamente. Embora ainda não tenha experimentado o ArcGIS Pro, na minha opinião, não me parece que a ESRI consiga acompanhar o ritmo.

“Ainda há coisas que sente falta do ArcGIS?” Claro que sim. Por exemplo, sinto falta de suporte para CMYK durante a exportação de mapas, mas não tanto como sinto falta do QGIS neste momento. Para além disso, sei que essas lacunas serão resolvidas mais cedo ou mais tarde.

No fundo, até gostei da oportunidade de voltar ao ArcGIS, pois permitiu-me reforçar a minha opinião acerca do QGIS. Tem tudo a ver com liberdade! Não só a liberdade de usar o programa quando e para o que bem entender (algo que para mim já era ponto assente), mas também a liberdade de controlar o programa em si e os seus outputs. Mantendo a facilidade de utilização para recém chegados e principiantes, muito foi feito para facilitar a vida de utilizadores experientes, e eles ficam eternamente agradecidos por isso (pelo menos eu fico).

Dito isto, The winner is… QGIS!!

O Fim

(de um artigo extremamente parcial)

Top Novas Funcionalidades do QGIS em 2015

EN | PT

Com o lançamento da primeira versão com suporte de longa duração (2.8 LTR) e mais duas versões estáveis (2.10 e 2.12), 2015 foi um ano fantástico (e atarefado) para a comunidade QGIS, com inúmeras melhorias e novas funcionalidades a chegarem ao QGIS.

Em jeitos de balanço, pedi aos utilizadores que escolhessem as funcionalidades introduzidas em 2015 suas favoritas (da lista do registo visual de alterações). Como resultado, obtive o seguinte top 5 de novas funcionalidades.

5 – Melhorias na consola python (2.8)

Com a versão 2.8, passou a ser possível arrastar e largar scripts Python para a janela do QGIS, sendo os mesmos executados automaticamente. Existe também um novo ícone na barra de ferramentas dos módulos e um atalho (Ctrl-Alt-P) para acesso rápido à consola Python.

4 – Novos algoritmos de processamento (2.8)

Também no 2.8, foram introduzidos novos algoritmos à framework de processamento. Se trabalha em análise espacial, estas adições poderão muito bem ter-lhe feito ganhar o dia (ou o ano).

  • Algoritmo Pontos regulares
  • Algoritmo Diferença simétrica
  • Algoritmo Separação de vectores
  • Algoritmo Grelha de vectores
  • Algoritmo de cálculo de curvas hipsométricas
  • Algoritmo Separar linhas com linhas
  • Reconstrução do algoritmo de manipulação de campos

3 – Simbolizar por regras em árvore na legenda (2.8)

Ao longo de 2015 foram feitas algumas melhorias à legenda do QGIS. A versão 2.8 trouxe-nos a visualização da legenda de camadas simbolizadas por regras em formato de árvore. Melhor que isso, cada nó da estrutura de árvore pode ser ligada ou desligada, possibilitando uma excelente flexibilidade na escolha de sub-camadas a desenhar no mapa.

2 – Ferramentas avançadas de edição (2.8)

Alguma vez desejou, no QGIS, desenhar linhas paralelas ou com ângulos rectos,  trancar as linhas a determinados ângulos ou distâncias e por aí a fora? Então as suas preces foram ouvidas. As ferramentas avançadas de edição começaram como módulo CADinput e foram integradas no QGIS na versão 2.8, adicionando-lhe mais um painel. O painel fica activo quando se procede ao desenho de geometrias.

Untitled

1 – Etiquetas por regras (2.12)

Esta era uma funcionalidade há muito esperada (pelo menos por mim), e foi votada pela maioria dos utilizadores. A partir da versão 2.12, é possível definir estilos de etiquetas com base em regras. Isto permite um ainda maior controlo sobre o posicionamento e estilo das etiquetas. Tal como no caso das camadas simbolizadas por regras, as regras das etiquetas podem ser agrupadas para permitir a definição das opções de estilo de uma forma extremamente fléxivel. Por exemplo, é possível desenhar etiquetas diferentes consoante o tamanho dos respectivos elementos (tal como é exemplificado na imagem).

image25

Houve outras funcionalidades a fazerem as delícias de muitos utilizadores. Por exemplo, as Melhorias/consistência na selecção de projecções (2.8), Melhorias no provider PostGIS (2.12), Módulo para validar geometrias e alinhar geometrias (2.12), Múltiplos estilos por camada (2.8).

Discorda desta lista? Então ainda vai a tempo de fazer valer o seu voto. Também pode consultar aqui os resultados na integra.

Obviamente, esta lista vale o que vale. Tratou-se de um mero exercício. Até porque, com a tamanha diversidade de utilizadores QGIS, seria impossível criar uma lista que nos agradasse a todos. Para além disso, houve muitos aperfeiçoamento, feitos em 2015, que poderão ter passado despercebidos à maioria dos utilizadores. Consulte o registo visual de alterações para ver a lista completa de funcionalidades e melhorias.

Em meu nome, a todos os programadores, patrocinadores e colaboradores do QGIS,

MUITO OBRIGADO PELO VOSSO FANTÁSTICO TRABALHO!I

desejo-vos um óptimo (e produtivo) 2016.

Obter os vértices de multipolígonos usando PostGIS

Obter os vértices de multipolígonos usando PostGIS

EN | PT

Hoje precisei criar uma view em PostGIS que me devolvesse os vértices de uma camada de multipolígonos. Para além disso, precisava que os mesmos viessem ordenados numericamente começando em 1, e com as respectivas coordenadas XY.

Screenshot from 2015-11-05 23:58:19

A tarefa parecia-me trivial – bastaria usar a função ST_DumpPoints() para obter os vértices – não fosse o facto dos polígonos em postGIS terem um vértice repetido (obrigatoriamente o último vértice tem de ser igual primeiro) que não me interessava mostrar.

Depois de algumas tentativas, cheguei à seguinte query:

CREATE OR REPLACE VIEW public.my_polygon_vertexes AS
WITH t AS -- Transformar os polígonos em sets de pontos
    (SELECT id_polygon,
            st_dumppoints(geom) AS dump
     FROM public.my_polygons),
f AS -- Tirar geometria e indices dos sets de pontos 
    (SELECT t.id_polygon,
           (t.dump).path[1] AS part,
           (t.dump).path[3] AS vertex,
           (t.dump).geom AS geom
     FROM t)
-- Obter todos os pontos filtrando o último ponto de cada parte das geometrias
SELECT row_number() OVER () AS gid, -- Criar um identificador único
       f.id_polygon,
       f.part,
       f.vertex,
       ST_X(f.geom) as x, -- extra: obter a coordenada X do ponto
       ST_Y(f.geom) as y, -- extra: obter a coordenada Y do ponto
       f.geom::geometry('POINT',4326) as geom -- garantir o tipo de geometria
FROM f 
WHERE (f.id_polygon, f.part, f.vertex) NOT IN
      (SELECT f.id_polygon,
              f.part,
              max(f.vertex) AS max
       FROM f
       GROUP BY f.id_polygon,
                f.part);

A parte interessante ocorre na cláusula WHERE, basicamente, da listagem total de vértices, são escolhidos apenas os que não se encontram numa lista de vértices com o valor de índice máximo do vértice por polígono e por parte, ou seja, o último vértice que cada parte de cada polígono.

Eis o resultado:

Screenshot from 2015-11-05 23:58:40

A vantagem desta abordagem (via PostGIS) em vez de usar a ferramenta “Polígonos  para linhas”, seguida de “Linhas para Ponto” é que basta alterar a minha camada de polígonos, e gravá-la, para ver os vértices a serem actualizados automaticamente. É nestas coisas que adoro o Postgis.

Dica para ajustar posição de símbolos em QGIS

EN | PT

De quando em vez aparecem-me zonas com demasiado símbolos no mesmo local, e pensei como seria fantástico se os pudesse arrastar para um local mais conveniente sem ter de alterar as suas geometrias, tal como é possível fazer com as etiquetas. Esse pensamento deu-me a ideia base para a dica que vou demonstrar.

Escolha a sua camada de pontos e comece por criar dois novos campos chamados symbX e symbY (Tipo: Decimal; Tamanho: 20; precisão: 5). No separador “Estilo” das propriedades da camada, defina para cada nível do seu símbolo o seguinte: Escolher “unidade do mapa” como a unidade para as opções de afastamento; Usar a seguinte expressão na opção afastamento das propriedades definidas por dados.


CASE WHEN symbX IS NOT NULL AND symbY IS NOT NULL THEN
    tostring($x - symbX) + ',' + tostring($y - symbY)
ELSE
    '0,0'
END

Screenshot from 2015-02-22 18:18:43

Tenha atenção que, se as coordenadas do seu mapa tiver valores negativos, será necessário uma pequena alteração ao código. E. g., se tiver valores negativos em X deverá usar-se  antes a expressão “tostring(symbX -$x)”.

De forma temporária coloque etiquetas na sua camada usando um texto pequeno (eu usei o ‘+’ (sinal de mais) centrado e com um buffer branco) e defina as coordenadas X e Y dos propriedades definidadas por dados usando os campos symbX e symbY,

Screenshot from 2015-02-22 22:42:07

A partir desse momento, quando usar a ferramenta de mover etiquetas, não só alterará a posição da etiqueta, mas também a do próprio símbolo! Fantástico, não?

anim

Note que as geometria dos elementos não são alteradas durante o processo. Para além disso, lembre-se que neste caso também poderá adicionar linhas de guia para ligar os símbolos à posição original do ponto.

Calcular coordenadas do centroide de polígonos

EN | PT

Tive necessidade de, numa camada de polígonos, adicionar colunas à tabela de atributos com as coordenadas dos centroides das geometria. Cheguei às seguintes expressões para calcular as coordenadas X e Y, respectivamente:

xmin(centroid($geometry))
ymin(centroid($geometry))

A expressão parece bastante banal, mas ainda demorei a perceber que, não existindo funções x(geometry) e y(geometry), podia usar as funções xmin() e ymin() para obter as coordenadas dos centroides dos polígonos. Uma vez que esta não foi a primeira vez que precisei de usar estas expressões, fica agora o registo para não me voltar a esquecer.

Etiquetas com guias em QGIS e Postgis

EN | PT

Recentemente tive necessidade de colocar etiquetas de texto em elementos com geometrias muito próximas, fazendo com que as mesmas colidissem umas com as outras.

Capturar_3

Controlando a posição das etiquetas através dos dados (para configurar rapidamente a camada usei o plugin “layer to labeled layer“) e usando a ferramenta do qgis para mover as etiquetas, foi relativamente fácil reposicioná-las de forma a que todas coubessem no mapa sem se sobreporem. Porém, em certos casos, tornou-se difícil perceber a que elemento cada uma correspondia.

Capturar_2

Precisava de criar “linhas de guia” que, sempre que necessário, ligassem o elemento e a respectiva etiqueta. Conhecia a existência de outro excelente plugin, chamado “Easy Custom Labeling” do Regis Haubourg, que fazia o que eu pretendia, mas como criava um duplicado da camada original significava que a mesma não seria actualizada quando a camada original fosse editada.

Uma vez que os dados estavam guardados numa base de dados PostgreSQL/Postgis, decidi criar uma consulta que me devolvesse uma camada com as linhas de guia. Usei a seguinte consulta no gestor de bases de dados:

SELECT
  gid,
  label,
  ST_Makeline(St_setSRID(ST_PointOnSurface(geom),27493), St_setSRID(St_Point(x_label::numeric, y_label::numeric),27493))
FROM
  epvu.sgev
WHERE
  x_label IS NOT NULL AND
  y_label IS NOT NULL AND
  NOT ST_Within(ST_Makeline(St_setSRID(ST_PointOnSurface(geom),27493), St_setSRID(St_Point(x_label::numeric, y_label::numeric),27493)),geom))

Esta consulta cria uma linha composta pelo centro (interno) do polígono e a coordenada do ponto para a qual a etiqueta foi movida. A última condição da cláusula WHERE garante que a linha só é criada se a coordenada da etiqueta não estiver dentro do polígono.

Capturar_1

Com a camada resultante carregada no meu projecto, basta-me mover as etiquetas e gravar a edição da camada original para que a respectiva linha de guia apareça.

guidelines

Séries de mapas com formatos múltiplos em QGIS 2.6 – Parte 2

EN | PT

No último artigo, tentei mostrar como usei o QGIS 2.6 para criar séries de mapas cuja orientação da folha se adaptasse à forma do elemento do atlas. Esse método é útil quando a escala final dos mapas não é relevante, ou quando os elementos usados no atlas têm uma dimensão muito semelhante, permitindo a adopção de uma escala única. No entanto, quando é necessário manter a mesma escala de impressão dos mapas e os elementos do atlas apresentam diferenças de extensão, é necessário alterar o tamanho da folha. Nesta segunda parte do artigo, tentarei mostrar como cheguei a uma solução para isso.

Como base usei o mapa criado na 1ª parte do artigo, do qual fiz um duplicado. Para exemplificar o método procurei criar uma série de mapas à escala 1:2.000.000. Uma vez que iria adaptar tanto a altura como a largura da folha aos elementos do atlas, não me precisava de preocupar com a orientação da folha em si e por isso comecei por desactivar as propriedades definidas por dados na opção orientação.

Fiz algumas contas usando a escala, as dimensões do elemento do atlas e as margens definidas anteriormente e e cheguei às seguintes expressões a usar na  largura e altura da folha, respectivamente:

((bounds_width( $atlasgeometry ) / 2000000.0) * 1000.0) * 1.1 + 10
((bounds_height( $atlasgeometry ) / 2000000.0) * 1000.0) * 1.1 + 30

Passo a explicar. (bounds_width( $atlasgeometry ) / 2000000.0) é a largura do elemento do atlas representado à escala 1:2.000.000 em unidades do projecto (neste caso metros). Este resultado é multiplicado por 1000 para o converter em milímetros (unidade usada nas definições do compositor). Para que o elemento de atlas não ficasse resvés aos limites do mapa decidi dar 10% de margem em torno do mesmo, o que justifica a multiplicação por 1.1. E por fim adicionei a dimensão das margens do mapa que tinham sido definidas na 1ª parte do artigo (i.e., 20 mm, 5 mm, 10 mm, 5 mm).

Screenshot from 2014-11-16 22:58:34

Como se pode ver pela imagem anterior, após a introdução das expressões nas opções de largura e altura da folha, a sua dimensão já se alterava em função do tamanho do elemento de atlas. No entanto, como seria de esperar, os itens do mapa mantiveram-se teimosamente na mesma posição. Foi por isso necessário alterar as expressões definidas para a dimensão e posição de cada um deles.

Começado pelo tamanho do item de mapa, as expressões a usar na altura e largura não foram difíceis de perceber uma vez que seriam as dimensões da folha menos as margens:

((bounds_width( $atlasgeometry ) / 2000000.0) * 1000.0) * 1.1
((bounds_height( $atlasgeometry ) / 2000000.0) * 1000.0) * 1.1

Screenshot from 2014-11-16 23:07:43

Para posicionar correctamente os elementos, bastou substituir nas expressões das opções X e Y os “CASE WHEN … THEN … END” que determinavam o tamanho da largura ou altura da folha, pelas expressões descritas anteriormente. Por exemplo, as expressões usadas para a posição da legenda em X e Y:

(CASE WHEN  bounds_width(  $atlasgeometry ) >=  bounds_height( $atlasgeometry) THEN 297 ELSE 210 END) - 7
(CASE WHEN  bounds_width(  $atlasgeometry ) >=  bounds_height( $atlasgeometry) THEN 210 ELSE 297 END) - 12

Passaram a ser, respectivamente:

(((bounds_width( $atlasgeometry ) / 2000000.0) * 1000.0) * 1.1 + 10) - 7
(((bounds_height( $atlasgeometry ) / 2000000.0) * 1000.0) * 1.1 + 30) - 12

Screenshot from 2014-11-16 23:22:40

Alterando as expressões de posicionamento X e Y dos restantes itens do compositor cheguei à estrutura final.

alaska_region_Kenai Peninsula

Depois disso, a impressão/exportação de todos os (25) mapas ficou, mais uma vez, à distância de um só clique.

mosaico_regioes_fixed

Uma vez que o QGIS permite exportar imagens do compositor georreferenciadas, adicionando-as ao QGIS obtive este resultado interessante.

Screenshot from 2014-11-17 00:02:38
Como se pode ver pelos resultados, através deste método, podemos obter mapas com formatos bastante estranhos. Por essa razão, na 3ª e última parte deste artigo, procurarei mostrar como criar uma série de mapas com escala fixa, mas usando formatos de folhas standard (A4, A3, A2, A1 e A0).

Séries de mapas com formatos múltiplos em QGIS 2.6 – Parte 1

EN | PT

Para não variar, a nova versão do QGIS (o QGIS 2.6 Brigthon) traz um conjunto alargado de novas funcionalidades que permitem ao utilizador fazer mais, melhor e mais rápido do que com a versão anterior. Uma das novidades desta versão é a possibilidade de controlar algumas propriedades dos itens do compositor através de dados (por exemplo, o tamanho e a posição). Algo que abre a porta a aplicações bastante interessantes. Nos próximos artigos, proponho-me a mostrar como criar séries de mapas com multiplos formatos.

Neste primeiro artigo, o objectivo é que, mantendo o tamanho da folha, o mapa seja criado com a orientação (paisagem ou retrato) que melhor se adapte à forma do elemento do atlas. Para exemplificar, usei a amostra de dados do Alaska para criar  um mapa de cada uma das regiões do Alaska.

Em primeiro lugar comecei por criar o meu layout numa dos formatos, colocando vários itens nas posições que desejava.

mapa_base_atlas

Para  controlar a orientação da folha através do atlas, fui ao separador “Composição” e na opção orientação, usei no botão propriedades definidos por dados a seguinte expressão:

CASE WHEN bounds_width( $atlasgeometry ) >=  bounds_height( $atlasgeometry ) THEN 'landscape' ELSE 'portrait' END

Usando a opção de pré-visualização do atlas, podemos verificar que a orientação da folha já muda de acordo com a forma do elemento do atlas. No entanto, os itens não acompanham essa mudança e alguns ficam até fora da área de impressão.

Screenshot from 2014-11-08 23:29:49

Para controlar o tamanho e posição dos itens do mapa tive em consideração o tamanho de uma folha A4 (297 x 210 mm), as dimensões das margens do mapa ( 20 mm, 5 mm, 10 mm, 5 mm) e os pontos de referência dos itens.

No caso do item “mapa”, usando como ponto de referência o canto superior esquerdo, foi necessário alterar a sua altura e largura. Sabia que a altura do item era é subtracção do tamanho das margens superiores e inferiores (30 mm) da altura folha por isso a expressão a usar foi:

(CASE WHEN  bounds_width(  $atlasgeometry ) >=  bounds_height( $atlasgeometry) THEN 297 ELSE 210 END) - 30

De forma análoga, a expressão a usar para a largura foi:

(CASE WHEN  bounds_width(  $atlasgeometry ) >=  bounds_height( $atlasgeometry) THEN 210 ELSE 297 END) - 10

Screenshot from 2014-11-09 00:02:15

Os restantes itens ocupavam sempre uma posição relativa na folha sem que fosse necessário alterar o seu tamanho e por isso tinha apenas de controlar a sua posição. Por exemplo, o título encontrava-se centrado no topo da folha, e portanto, usando como ponto de referência o topo-centro, bastou definir a seguinte expressão para a posição X:

Screenshot from 2014-11-09 00:13:17

(CASE WHEN  bounds_width(  $atlasgeometry ) >=  bounds_height( $atlasgeometry)  THEN 297 ELSE 210 END)  / 2.0

Screenshot from 2014-11-09 00:30:57

Já a legenda exige alterar a posição em X e em Y. Usando como ponto de referência o canto inferior direito, a expressão para a posição em X foi:

(CASE WHEN  bounds_width(  $atlasgeometry ) >=  bounds_height( $atlasgeometry) THEN 297 ELSE 210 END) - 7

E para a posição em Y:

(CASE WHEN  bounds_width(  $atlasgeometry ) >=  bounds_height( $atlasgeometry) THEN 210 ELSE 297 END) - 12

Screenshot from 2014-11-09 00:47:28

Para os restantes itens (rosa dos ventos, escala gráfica e texto no canto inferior esquerdo), as expressões a usar eram em tudo similares às já apresentadas, e, após definidas em cada um dos itens, fiquei com o layout preparado para se adaptar às duas orientações da folha.

output_9

Depois disso, a impressão/exportação de todos os (25) mapas ficou à distância de um só clique.

mosaico_regioes

No próximo artigo da série, procurarei explicar como criar séries de mapas em que seja o tamanho da folha a adaptar-se de forma a manter uma escala constante.

Instalar duas versões de QGIS em Linux

Instalar duas versões de QGIS em Linux

QGIS24_QGISmaster

Em altura de testes à versão em desenvolvimento do QGIS (versão master), dá jeito  ter também instalada a última versão estável do QGIS. Em windows isso não representa um problema, uma vez que se podem instalar várias versões do QGIS em paralelo (tanto via Osgeo4w como standalone). Em linux, o processo não é tão directo pelo facto da instalação se realizar por obtenção de diversos pacotes disponíveis nos repositórios, não sendo por isso possível instalar mais do que uma versão sem que se originem quebras de dependências. Assim, instalando a versão estável através dos repositórios, as alternativas para instalação da versão em desenvolvimento são:

  • Compilar o QGIS master do código fonte;
  • Instalar o QGIS master num docker;
  • Instalar o QGIS master numa máquina virtual;

Neste artigo vou mostrar como compilar o código fonte em Ubuntu 14.04. Afinal não é tão difícil quanto parece. Meia dúzia de comandos e um pouco de paciência e vai-se lá. Usei como base as indicações do ficheiro INSTALL.TXT disponível no código fonte com umas pequenas alterações.

Instalar todas as dependências necessárias

Num terminal correr o seguinte comando para instalar todas as dependências e ferramentas necessárias à compilação do QGIS. (adicionei o ccmake e o git ao comando original)

sudo apt-get install bison cmake doxygen flex git graphviz grass-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl0-dev libopenscenegraph-dev libosgearth-dev libpq-dev libproj-dev libqscintilla2-dev libqt4-dev libqt4-opengl-dev libqtwebkit-dev libqwt5-qt4-dev libspatialindex-dev libspatialite-dev libsqlite3-dev lighttpd pkg-config poppler-utils pyqt4-dev-tools python-all python-all-dev python-qt4 python-qt4-dev python-sip python-sip-dev spawn-fcgi txt2tags xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb cmake-curses-gui

Configurar o ccache

Este passo permite optimizar a compilação e tornar a compilação mais rápida nas próximas vezes que se fizer:

cd /usr/local/bin
sudo ln -s /usr/bin/ccache gcc
sudo ln -s /usr/bin/ccache g++

 Obter o código fonte do Github

O código fonte pode ser colocado numa pasta à escolha de cada um. Seguindo a sugestão do ficheiro de instruções acabei por colocar tudo na minha pasta home/alexandre/dev/cpp.

mkdir -p ${HOME}/dev/cpp
cd ${HOME}/dev/cpp

Já dentro da pasta home/alexandre/dev/cpp, podemos obter o código do qgis executando o seguinte comando git:

git clone git://github.com/qgis/QGIS.git

Nota: Se pretendesse fazer alterações ao código e experimentar se funcionava, então deveria fazer o clone do fork do qgis do meu próprio repositório, ou seja:

git clone https://github.com/SrNetoChan/Quantum-GIS

Preparar directorias de compilação e instalação

O código fonte tem de ser compilado e instalado em locais próprios para evitar conflitos com outras versões do QGIS. Por isso, há que criar uma pasta para efectuar a instalação:

mkdir -p ${HOME}/apps

E outra onde será feita a compilação:

cd QGIS
mkdir build-master
cd build-master

Configuração

Já na pasta build-master damos início ao processo de compilação. O primeiro passo é a configuração, onde vamos dizer onde queremos instalar o QGIS master. Para isso executamos o seguinte comando (não esquecer os dois pontos):

ccmake ..

Na configuração é necessário alterar o valor do CMAKE_INSTALL_PREFIX que define onde vai ser feita a instalação, no meu caso usei a pasta já criada ‘home/alexandre/apps’ . Para editar o valor há que mover o cursor até à linha em causa e carregar em [enter], depois de editar, volta-se a carregar em [enter]. Depois há que carregar em [c] para refazer a configuração e depois em ‘g’ para gerar a configuração.

Screenshot from 2014-10-08 23:33:39

 Compilação e instalação

Já com tudo configurado resta compilar o código e depois instalá-lo:

make
sudo make install

Nota: Estes dois passos podem demorar um bocadinho, principalmente na primeira vez que o código for compilado.

Depois de instalado podemos correr o QGIS master a partir da pasta de instalação:

cd ${HOME}/apps/bin/
export LD_LIBRARY_PATH=/home/alexandre/apps/lib
export QGIS_PREFIX_PATH=/home/alexandre/apps
${HOME}/apps/bin/qgis

Para se tornar mais cómodo, podemos colocar os últimos 3 comandos num ficheiro .sh e gravá-lo num local acessível (desktop ou home) para executarmos o qgis sempre que necessário.

Screenshot from 2014-10-09 00:36:52

UPDATE: Actualizar a versão master

Como já foi referido num comentário, a versão em desenvolvimento está constantemente a ser alterada, por isso para testar se determinados bugs foram entretanto corrigidos há que a actualizar. Trata-se de um processo bastante simples. O primeiro passo é actualizar o código fonte:

cd ${HOME}/dev/cpp/qgis
git pull origin master

E depois é voltar a correr a compilação (que desta feita será mais rápida):

cd build-master
ccmake ..
make
sudo make install