Welcome to Planet OSGeo

December 13, 2018

Quest’anno mi porto avanti di qualche settimana rispetto al ritardo astronomico maturato negli anni e pubblico la lista dei pochi libri che ho letto nel 2017.

Il 2017 è stato l’anno in cui sono diventato papà, in cui ho traslocato dalla città dove è nato mio figlio a quella dove sono nato io ma dove non avevo quasi mai abitato, in cui ho cambiato lavoro per poter finalmente continuare a fare il mio mestiere. Quindi, scusate se ho letto troppo poco. Anche nel 2017 non ho letto nessun libro che non fosse scritto in italiano (mica intenzionalmente).

Ho anche iniziato a tenere traccia dei libri su inventaire.io.

Piero Colaprico, Trilogia della città di M.

Questo libro mi è stato donato da Stefano R., nativo della città di M., quando ho iniziato a lavorare nella città di M. il 13 dicembre 2017. L’ho consumato nei vagoni ferroviari prima dell’alba e dopo il tramonto viaggiando quotidianamente da Genova.

Le tre storie in cui si muove l’ispettore Bagni sono ambientate in una città di mezzo, tra quella vecchia che sta scomparendo e lascia il tempo ad una nuova. Muovendomi nella zona del Ticinese più volte ho provato la sensazione di essere stato in quei luoghi. Non sono un assiduo frequentatore della letteratura di genere, ma se leggo un poliziottesco, ora preferisco Bagni ai suoi colleghi più televisivi.

Wu Ming 1, Un viaggio che non promettiamo breve

Ho iniziato a leggere questo libro verso fine anno, proprio come la Trilogia ad inizio articolo, viaggiando in treno lungo uno dei percorsi che dovrebbero essere toccati dalle Grandi Opere. E poiché il libro racconta con estrema precisione la realtà, ho faticato ad ogni pagina a reggere il peso di tutte le nefandezze, e per adesso non ho letto che un terzo del libro, forse un po’ meno.

È un libro che deve essere letto, perché è una storia che non è ancora conclusa e da queste parti oltre alla inutile e dannosa TAV abbiamo un altrettanto inutile terzo valico ferroviario, mentre le linee ferroviarie già esistenti del pendolarismo quotidiano sono in frantumi.

Edmund De Waal, La strada bianca

Questo è un libro di cui mi sono innamorato vedendo la copertina in vetrina nella mia libreria. A me piacciono le copertine che raccontano qualcosa del libro, e questa era già di per sé meritevole di essere portata a casa, anche se non ci fosse stato il libro dentro.

Ho letto il primo capitolo con l’emozione di chi scopre un tesoro. L’ho dovuto persino rileggere a voce alta, per poterlo capire in tutta la sua poesia. Questo libro è stato compagno di viaggio tra la fine del 2016 e l’inizio del 2017.}

Non ho mai letto Un’eredità di avorio e ambra, che pure è sulla libreria di casa da anni. Non avevo capito bene di cosa si trattasse, potrei dire.

Per me la ceramica, e quindi anche la porcellana, è un elemento primordiale a cui ho dedicato moltissima parte della mia vita adulta, soprattutto manipolando, guardando, osservando migliaia di vasi rotti. Leggerne una storia raccontata in prima persona è stato un percorso di ricucitura, una forma di kintsugi letterario.

Marco Danielli, Uscita di sicurezza

Marco è prima di tutto un collega, che potrebbe sembrare molto versatile, vista la varietà di ruoli che ha rivestito nella vita in situazioni molto diverse. È stata una grande sorpresa scoprire che è anche un abile scrittore.

Un romanzo d’esordio finemente costruito che combina realtà autobiografica e finzione letteraria.

Igiaba Scego, Adua

Non so se i quattro lettori assidui di questa rubrica ci hanno fatto caso, ma da qualche anno leggo sempre almeno un libro di Africa. Quest’anno, addirittura due.

Leggere di Africa è inevitabilmente una seduta di colonialismo, di post-colonialismo, oltre che di un continente non misurabile, privo di significato a meno di non essere distorto da una proiezione geografica sbagliata. Nel caso clinico italiano credo si possa parlare a buon diritto di post-colonialismo assente – autrici come Igiaba Scego sono ogni giorno lì a smontare il buonismo, soprattutto con storie come quella di Adua, ben più di un romanzo storico.

Chinua Achebe, Le cose crollano

Ricevuto in dono e letto con gusto, questo primo libro della trilogia è un gioiello di grande profondità storica e soprattutto epica. Achebe muove e colpisce i suoi personaggi con l’eleganza di un vero classico. Leggendo è stato impossibile non rispecchiarsi nelle pagine di Congo, così totalmente diverso eppure intrecciato nelle stesse vicende storiche.

by Stefano Costa at December 13, 2018 08:45 PM

Entre os dias 20 e 23 de novembro aconteceu em Melbourne (Austrália) o FOSS4G SoTM Oceania um evento regional que cria um link focado na Oceania em uma comunidade global, apoiada pela OSGeo Foundation e pela OpenStreetMap Foundation (OSMF).

No evento foram abordados diversos assuntos interessantes, e vale a pena dar uma olhada nas apresentações, que estão disponíveis gratuitamente no YouTube. Veja:

1. Apresentação (Boas Vindas)

2. Keynotes

3. Sessões especiais

4. Palestras

by Fernando Quadro at December 13, 2018 10:30 AM

December 12, 2018

Hace unas semanas finalizó la segunda edición del concurso denominado ‘Proyectos con estudiantes y gvSIG Batoví’. A modo de titular se podría decir de manera muy simplista que se trata de un concurso que premia los mejores trabajos realizados con gvSIG Batoví (una adaptación de gvSIG Desktop) por estudiantes de secundaria de Uruguay.

Pero este concurso es mucho más, es un ejemplo de como llevar con inteligencia y trabajo los Sistemas de Información Geográfica, el software libre gvSIG, a las aulas. El concurso, a la postre, es el incentivo que permite enganchar a los alumnos, pero en este post quería resaltar las tareas principales que hay detrás.

Fase 0. Antes de empezar

No se puede llevar una nueva tecnología a las aulas sin capacitar a los profesores, y teniendo esto en mente se consideró fundamental el realizar como primer paso unas jornadas de capacitación de docentes. Al finalizar la actividad se conformó un equipo de seguimiento de gvSIG Batoví integrado por los asistentes al taller con el objetivo de monitorear el uso y aplicación de gvSIG Batoví en tareas de docencia y en los diferentes sub-sistemas educativos.

Además, para facilitar el manejo de la herramienta, se realizaron distribuciones de gvSIG Desktop adaptadas al entorno educativo para los equipos del Plan Ceibal (Ubuntu) y particulares (disponible también para Windows) y una serie de manuales y tutoriales relacionados con la instalación y ejecución de gvSIG Batoví.

Y reincidiendo en la importancia de la capacitación a docentes, se diseño una propuesta de b-learning, que es el nombre que se conoce para definir una combinación de formación presencial y online. Más de 150 profesores de todo el país se inscribieron a esta formación. En este enlace podéis consultar la documentación que se generó para servir como guía de los talleres.

Fase 1. Desarrollando los proyectos

Pasando ya al concurso en sí, además de definir las bases y premios, se realizó un convenio con la Facultad de Ingeniería (UdelaR) para la designación de tutores estudiantes de la Tecnicatura de Cartografía para cada equipo participante. Conectando así a los estudiantes universitarios con los de los liceos.

Ya estaba todo listo para empezar a trabajar en los proyectos…y para ello se crearon espacios en la plataforma CREA (de aprendizaje en línea), para cada proyecto, para el seguimiento de los mismos, evacuación de dudas, intercambio de información, etc. El seguimiento se complementó con intercambios entre el equipo coordinador y los equipos mediante videoconferencias.

Fase 2. El concurso

Llegado el momento se procedió por cada uno de los equipos participantes a la defensa de los proyectos mediante videoconferencias. Y por último, una actividad presencial para compartir, de socialización de los resultados, entrega de premios, diplomas y certificados

El grupo que realizó el proyecto galardonado con el primer premio estudió el vínculo existente entre el rendimiento de sus compañeros y compañeras con la distancia de la que viven respecto al liceo. Para ello, referenciaron los lugares donde viven los estudiantes, el medio en el que se trasladan, el rendimiento (materias con nota insuficiente y llegadas tarde) y nivel de repetición. ¡Bravo!

Fase 3. Después de…

No todo acaba con la entrega de premios. Es el momento de la tarea de evaluación y valoración con profesores referentes y tutores.

Por cierto, aquí tenéis el acceso a los proyectos finalistas, aunque en mi opinión con este tipo de iniciativas sólo hay ganadores. Ojalá y veamos replicada esta iniciativa en otras partes del planeta. A mi me encantaría ver algo así en mi tierra ¿y a vosotros?

by Alvaro at December 12, 2018 06:45 PM


The IOSA Radiocarbon Calibration Library (IOSACal) is an open source calibration software. IOSACal is meant to be used from the command line and installation, while straightforward for GNU/Linux users, is certainly not as easy as common desktop apps. To overcome this inconvenience, I dedicated some efforts to develop a version that is immediately usable.

The IOSACal web app is online at https://iosacal.herokuapp.com/.

This is a demo service, so it runs on the free tier of the commercial Heroku platform and it may take some time to load the first time you visit the website. It is updated to run with the latest version of the software (at this time, IOSACal 0.4.1, released in May).

Since it may be interesting to try the app even if you don’t have a radiocarbon date at hand, at the click of a button you can randomly pick one from the open data Mediterranean Radiocarbon dates database, and the form will be filled for you.

The random date picker in action The random date picker in action

Unfortunately, at this time it is not possible to calibrate or plot multiple dates in the web interface (but the command-line program is perfectly capable of that).

IOSACal Web is made with Flask and the Bootstrap framework, and the app itself is of course open source.

IOSACal is written in the Python programming language and is based on Numpy, Scipy and Matplotlib. This work wouldn’t be possible without the availability of such high quality programming libraries.

by Stefano Costa at December 12, 2018 01:27 AM

December 11, 2018

The OpenGeo (now called Boundless) PostGIS tutorial has long been my recommendation for people just getting started with PostGIS. It provides a broad intro to PostGIS, great for users new to SQL.

Unfortunately they recently removed it from their website. The guide was a fairly old now, so I don’t blame them. But it was a great free resource.

Luckily Archive.org has saved a copy of it. The course was based on open data, so compiling a similar dataset to complete the course was not difficult.

The course can be accessed at:

https://web.archive.org/web/20170913113658/http://workshops.boundlessgeo.com/postgis-intro/welcome.html

And the data can be accesses at (choose the green Clone or download button and Download ZIP):

https://github.com/HeikkiVesanto/postgis_course_data

I would skip the Loading spatial data chapter (very dated at this stage), and just use the ogr2ogr commands in the GitHub readme. Great chance to get started with ogr2ogr as well.

The data is also not 100% the same as the original. So some of the queries will have to be modified. Particularly the neighborhoods are different. So they may have slightly different names/boundaries/capitalization. So keep that in mind when creating your queries, and interpreting the results. But overall the data is pretty similar.

Also, if/when the Archive.org is gone that will likely be the end of the tutorial. So I would not waste any time completing the it.

by Heikki Vesanto at December 11, 2018 08:00 AM

December 10, 2018

Neste post (o último da série) veremos o teste do plugin que criamos para o QGIS.

1. MOCKING

Para testar um plugin do QGIS você precisa simular o ambiente que ele deve rodar. E esse ambiente é obviamente o próprio QGIS, mas não é possível iniciar o QGIS toda vez que você executa um teste. Felizmente, há o QGIS Mocking para lhe auxiliar.

2. VOCÊ PRECISA DE DADOS

Cada teste é executado repetidas vezes, o que significa que ele precisa redefinir os dados que estão sendo usados ​​para seu estado padrão. Isso pode ser um “PIDA” se o teste alterar os dados de maneira imprevisível.

Usando as camadas do QGIS, você pode preparar novos dados para cada um dos seus testes, colocando de forma eficaz todo o processo de manipulação de dados.

3. ESCREVENDO TESTES

Cada um dos testes do plugin AttributeTransfer herda da classe unittest.TestCase, que vem com vários métodos que você pode estar familiarizado com outros idiomas: setUp() é executado antes para cada método de teste, enquanto tearDown() é executado após cada um deles. Os testes são definidos como métodos cujos nomes começam com a palavra test.

Cada teste deve chamar algum método assertWhatever que verifica se o teste foi aprovado ou não. Aqui está um exemplo de tal teste cobrindo camadas não pontuais.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2017-11-18 18:40:50
# @Author  : Michal Zimmermann <zimmicz@gmail.com>

import os
import sip
import sys
import unittest
from qgis.core import QgsMapLayerRegistry, QgsVectorLayer, QgsFeature, QgsGeometry, QgsPoint
from utilities import get_qgis_app

sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/..")
from attribute_transfer import AttributeTransfer
from create_dummy_data import create_dummy_data_polygon_or_line

sip.setapi('QtCore', 2)
sip.setapi('QString', 2)
sip.setapi('QDate', 2)
sip.setapi('QDateTime', 2)
sip.setapi('QTextStream', 2)
sip.setapi('QTime', 2)
sip.setapi('QUrl', 2)
sip.setapi('QVariant', 2)

QGIS_APP = get_qgis_app()
IFACE = QGIS_APP[2]


class AttributeTransferTestPolygonOrLine(unittest.TestCase):

    def setUp(self):
        self.source_layer = QgsVectorLayer(
            "Polygon?crs=epsg:4326&field=id:integer&field=textAttr:string&field=intAttr:integer&field=decAttr:double&field=dateAttr:date&index=yes", "source layer", "memory")
        self.target_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer&index=yes", "target layer", "memory")
        self.widget = AttributeTransfer(IFACE)

        registry = QgsMapLayerRegistry.instance()
        registry.removeAllMapLayers()
        registry.addMapLayers([self.source_layer, self.target_layer])
        create_dummy_data_polygon_or_line(self.source_layer, self.target_layer)
        self.widget.initGui()
        self.widget.vectors = [self.source_layer, self.target_layer]
        self.widget.editable_vectors = [self.source_layer, self.target_layer]
        self.widget.dlg.sourceLayer.addItems(["source layer", "target layer"])

    def test_text_attr(self):
        ATTRIBUTE_NAME = "textAttr"
        ATTRIBUTE_INDEX = 1

        self._test_attr(ATTRIBUTE_NAME, ATTRIBUTE_INDEX)

    def test_int_attr(self):
        ATTRIBUTE_NAME = "intAttr"
        ATTRIBUTE_INDEX = 2

        self._test_attr(ATTRIBUTE_NAME, ATTRIBUTE_INDEX)

    def test_dec_attr(self):
        ATTRIBUTE_NAME = "decAttr"
        ATTRIBUTE_INDEX = 3

        self._test_attr(ATTRIBUTE_NAME, ATTRIBUTE_INDEX)

    def test_date_attr(self):
        ATTRIBUTE_NAME = "dateAttr"
        ATTRIBUTE_INDEX = 4

        self._test_attr(ATTRIBUTE_NAME, ATTRIBUTE_INDEX)

    def test_existing_attr(self):
        ATTRIBUTE_NAME = "id"
        ATTRIBUTE_INDEX = 0

        self.widget.dlg.sourceAttribute.setCurrentIndex(ATTRIBUTE_INDEX)
        self.widget.dlg.targetAttribute.setText(ATTRIBUTE_NAME)

        self.assertEqual(
            self.widget.dlg.sourceAttribute.currentText(), ATTRIBUTE_NAME)
        self.assertFalse(self.widget.transfer())

    def _test_attr(self, attr_name, attr_index):
        self.widget.dlg.sourceAttribute.setCurrentIndex(attr_index)
        self.widget.dlg.targetAttribute.setText(attr_name)

        self.assertEqual(
            self.widget.dlg.sourceAttribute.currentText(), attr_name)

        self.widget.transfer()

        target_fields = [f.name()
                         for f in self.target_layer.dataProvider().fields()]
        self.assertIn(attr_name, target_fields)

        source_features = [f for f in self.source_layer.getFeatures()]
        target_features = [f for f in self.target_layer.getFeatures()]

        for idx, f in enumerate(source_features):
            self.assertEqual(f.attribute(attr_name), target_features[
                             idx].attribute(attr_name))


if __name__ == "__main__":
    unittest.main()

Com esse teste encerro a série de posts sobre como desenvolver um plugin para o QGIS. Espero que tenha ajudado a você que está querendo criar ou está criando o seu plugin para o QGIS.

Esta série de posts é tradução e uma adaptação livre do post escrito originalmente por Michal Zimmermann do blog “Pieces of knowledge from the world of GIS.

Fonte: Pieces of knowledge from the world of GIS

by Fernando Quadro at December 10, 2018 10:30 AM

December 06, 2018

Nesse link você pode acessar todo código-fonte do plugin QGIS AttributeTransfer.

O plugin em si se encontra no arquivo attribute_transfer.py. Quando o método run() é invocado, o formulário QT aparece com combos pré-preenchidos com camadas vetoriais disponíveis que suportam a edição de atributos.

Os combos de camada de origem e destino são mutuamente exclusivos, portanto, não é possível transferir o atributo dentro da mesma camada.

Codificando o plugin, é possível se deparar com pequenos problemas relacionados principalmente à implementação da QgsSpatialIndex. Na parte de análise do vizinho mais próximo, o método QgsSpatialIndex.nearestNeighbor foi mencionado. No entanto, esse método funciona apenas com geometrias do tipo QgsPoint. Com ele é impossível de obter geometrias do tipo QgsPolygon ou QgsPolyline, no entanto. O que podemos fazer, para lidar com esse problema? Bem… desenhe uma matriz de solução.

Usar o índice espacial traz mais um problema que foi percebido logo após a implementação dos fluxos de trabalho de comparação espacial para diferentes tipos de geometria. Há uma chance de encontrar o recurso mais próximo usando a caixa delimitadora que, na verdade, não é o recurso mais próximo. Nesse caso, optou-se por encontrar o vértice mais distante de tal recurso e utilizá-lo para construir o retângulo ao redor do recurso de destino. Se houver algum recurso de origem em tal retângulo, é muito provável que um deles seja o recurso real mais próximo.

Você pode ter pensado que esta seria a última parte da série. Mas como alguém poderia reivindicar o projeto de codificação sem escrever testes? Fique ligado no próximo post.

by Fernando Quadro at December 06, 2018 10:30 AM

December 05, 2018

Depois de mexer no console do QGIS Python e implementar a análise de vizinho mais próximo, vamos criar uma GUI muito simples para o plug-in.

Embora os documentos da API do QGIS levassem algumas horas para serem entendidos, o ecossistema do PyQGIS me ajudou muito. Aqui vem a lista de ferramentas que você deve incorporar ao seu processo de desenvolvimento o mais rápido possível.

1. CONSTRUTOR DE PLUG-INS

O QGIS Plugin Builder é um plugin criado para criar outros plugins. Ele permite você criá-lo em minutos e que você codifique em vez de configurar coisas que você não quer configurar. Note que você deve colocar o plugin dentro da pasta de plugins do QGIS (o padrão é ~/.qgis2/python/plugins) no Linux.

Lembre-se de rodar pyrcc4 -o resources.py resources.qrc dentro da pasta do seu plugin antes de adicioná-lo ao QGIS.

2. PLUGIN RELOADER

O QGIS Plugin Reloader é um plugin (possivelmente criado com o QGIS Plugin Builder) que permite que você atualize (reload) o seu plugin enquanto você codifica. Nenhuma reinicialização do QGIS é necessária.

3. QT DESIGNER

O Qt Designer vem com o pacote qt4-designer no Ubuntu. Ele é feito sob medida para projetar e construir GUIs a partir de componentes do Qt que podem ser usados ​​dentro do QGIS. Sua interface de arrastar e soltar permite prototipar rapidamente.

Graças ao Plugin Builder, você pode carregar o arquivo attribute_transfer_dialog_base.ui diretamente no Qt Designer e ajustá-lo às suas necessidades.

Não é preciso muito, apenas um QLineEdit e alguns QComboBoxwidgets. Eles estarão disponíveis no arquivo attribute_transfer.py como propriedades da classe AttributeTransferDialog.

O nome do widget pode ser personalizado na barra lateral direita e eu aconselho você a fazer isso. Eu escolhi o seguinte:

Uma vez carregado com Plugins -> Gerenciar e Instalar Plugins -> AttributeTransfer, o plugin está disponível diretamente na barra de ferramentas ou no menu Vetor. Está faltando a lógica de negócios, mas nós já fizemos isso no post anterior. Tudo o que deve ser fazer é unir essas duas partes.

by Fernando Quadro at December 05, 2018 10:30 AM

December 04, 2018

No último post foi descrito o básico da manipulação de camadas vetoriais. Como o nosso objetivo é criar um plug-in personalizado totalmente funcional com base em uma distância, gostaria de discutir a indexação espacial e a análise do vizinho mais próximo.

A figura acima ilustra a tarefa que pode ser resolvida apenas usando a API do QGIS. Imagine que você tenha uma camada de origem com um atributo preenchido com valores. Você recebe uma camada de destino também, infelizmente, os valores nesta camada estão faltando (não tão raros no mundo GIS, certo?). No entanto, você sabe que o valor ausente de cada recurso na camada de destino pode ser preenchido pelo valor de seu vizinho mais próximo da camada de origem. Como você faz isso?

1. GERANDO DADOS FICTÍCIOS

Vamos criar dois conjuntos de dados na memória com atributos id e value. Ambos terão dez recursos.

from qgis.core import QgsMapLayerRegistry, QgsVectorLayer, QgsFeature, QgsGeometry, QgsPoint, QgsSpatialIndex
from qgis.utils import iface

source_layer = QgsVectorLayer("point?crs=epsg:4326&field=id:integer&field=value:integer", "Source layer", "memory")
target_layer = QgsVectorLayer("point?crs=epsg:4326&field=id:integer&field=value:integer", "Target layer", "memory")

def create_dummy_data():

    source_layer.startEditing()
    target_layer.startEditing()

    feature = QgsFeature(source_layer.pendingFields())

    for i in range(10):
        feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(i, i)))
        feature.setAttribute("id", i)
        feature.setAttribute("value", i)
        source_layer.addFeature(feature)

    feature = QgsFeature(source_layer.pendingFields())

    for i in range(10):
        feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(i + i, i)))
        feature.setAttribute("id", i)
        target_layer.addFeature(feature)

    source_layer.commitChanges()
    target_layer.commitChanges()

    QgsMapLayerRegistry.instance().addMapLayer(source_layer)
    QgsMapLayerRegistry.instance().addMapLayer(target_layer)

create_dummy_data()

2. ESCREVENDO VALORES DO VIZINHO MAIS PRÓXIMO

A análise real do vizinho mais próximo pode ser feita em dez linhas de código! Primeiro, o qgis.core.QgsSpatialIndex é construído a partir de todos os recursos source_layer. Então, você itera sobre os recursos target_layer e para cada um deles, obtém apenas um ( nearestNeighbor(f.geometry().asPoint(), 1)[0]) vizinho mais próximo. Por fim, você apenas grava o valor do atributo do vizinho mais próximo na camada de destino e confirma as alterações.

def write_values_from_nn():
    source_layer_index = QgsSpatialIndex(source_layer.getFeatures())
    source_layer_features = {feature.id(): feature for (feature) in source_layer.getFeatures()}
    target_layer_features = target_layer.getFeatures()

    target_layer.startEditing()

    for f in target_layer_features:
        nearest = source_layer_index.nearestNeighbor(f.geometry().asPoint(), 1)[0]
        value = source_layer_features[nearest].attribute("value")
        target_layer.changeAttributeValue(f.id(), 1, value)

    target_layer.commitChanges()

write_values_from_nn()

3. O QUE VEM POR AI

Estamos um pouco mais perto do nosso objetivo. O que esta faltando?

  • Verificações de capacidades: a camada de destino suporta edições? Verifique os recursos do provedor de dados da camada para descobrir.
  • Registro do usuário: avisos ou erros estão completamente ausentes. Será ótimo tê-los apresentados dentro do qgis.gui.QgsMessageBar.
  • Atributos customizados: essa versão espera que as duas camadas tenham o mesmo atributo com o mesmo tipo de dados.
  • GUI : um widget PyQt transformará esse script baseado em console em um plug-in personalizado. Isso é o que vamos ver no próximo post.

by Fernando Quadro at December 04, 2018 10:30 AM

I ran into a process where I wanted to create copies of rasters in PostgreSQL. While seemingly a simple process this took me a bit of work to figure out.

For my workflow I had three rasters, which all have the same size, and I want to load them into the same PostGIS table with three raster geometry columns. I don’t think this will work for different sized rasters since the rid’s will not match.

Three rasters:
raster1
raster2
raster3

Which I want to copy into:
merged_raster

First to create the merged raster table:

CREATE TABLE merged_raster
(
  rid serial NOT NULL,
  raster1 raster,
  raster2 raster,
  raster3 raster
);

Then to add the rid’s. These are the id’s of the tiles that the raster was split into when loading. If your tile size is large enough then you may only have one.

INSERT INTO merged_raster(rid)
(SELECT rid FROM raster1);

Then copying the actual data is straighforward (this assumes the raster column in the raster1 datasets is called rast):

UPDATE merged_raster m
SET raster1 = r.rast
FROM raster1 r
WHERE r.rid = m.rid;

UPDATE merged_raster m
SET raster2 = r.rast
FROM raster2 r
WHERE r.rid = m.rid;

UPDATE merged_raster m
SET raster3 = r.rast
FROM raster3 r
WHERE r.rid = m.rid;

Now I still have an issue that QGIS will not load these layers. It will always load the initial raster column no matter what is chosen.

by Heikki Vesanto at December 04, 2018 09:00 AM

December 03, 2018

It’s December and that means it is time to plan for the next year. Planning also means preparing a budget and to do so, we would like to learn more about what you think QGIS.ORG should focus on: features or bug fixing and polishing? Therefore, we invite you to our QGIS user question of December 2018.

We also have localized translated versions of this questionnaire for our French-speaking and Portuguese-speaking users.

Your answers in November

In November, we wanted to know which version of QGIS you use.

by underdark at December 03, 2018 08:59 PM

The next International QGIS User Conference and Developer Meeting will take place in the week from 4 to 10 March 2019 in A Coruña (Spain).

 

coru
The call for presentations and workshop registration is out and you can apply using the online registration form. Note that the deadline for presenting proposals is 21 Dec 2019. If you need any info please email your queries to: userconf2019@qgis.es

 

The International QGIS User and Developer Conference wants to be the reference conference for the QGIS community, a meeting point for the family of users and developers associated with the QGIS project. Attending the conference is an opportunity to gather experience and share knowledge about QGIS. The language of the conference is English.

 

The event is organized by the Spanish QGIS Association [1], the Spanish user group, and the Galician Xeoinquedos community [2] with the help of A Coruña municipality [3]. The event is under the QGIS.org umbrella. We look forward to seeing you there!

 

 

by Tim Sutton at December 03, 2018 06:07 PM

Como mencionado na parte anterior da série, o console Python é um ponto de entrada para a automação do fluxo de trabalho GIS dentro do QGIS. Lembre-se de que existe um objeto iface representando a instância qgis.gui.QgisInterface dentro do console que lhe dá acesso a toda a GUI do QGIS. Vamos ver o que podemos fazer dentro do console.

1. CARREGANDO A PASTA DE CAMADAS VETORIAIS

import glob
from qgis.core import QgsMapLayerRegistry, QgsVectorLayer

def load_folder(folder):
    VALID_EXTENSIONS = ('.geojson', '.gpkg', '.shp')
    files = [f for f in glob.glob("{}/*".format(folder)) if f.endswith(VALID_EXTENSIONS)]

    for f in files:
        layer = QgsVectorLayer(f, f.split('/')[-1], 'ogr')

        if not layer.isValid():
            iface.messageBar().pushCritical("Failed to load:", f)
            continue

        QgsMapLayerRegistry.instance().addMapLayer(layer)

load_folder("path/to/your/vector/files/folder")
  • QgsMapLayerRegistry representa o painel de camadas presente na GUI do QGIS
  • iface.messageBar() retorna a barra de mensagens do aplicativo principal e permite notificar o usuário sobre o que está acontecendo
  • QgsVectorLayer representa uma camada vetorial com seus conjuntos de dados vetoriais subjacentes

2. EDIÇÃO DA TABELA DE ATRIBUTOS DA CAMADA ATIVA

O código a seguir demonstra a possibilidade de editar a tabela de atributos da camada vetorial por meio do console.

  • Qualquer atributo a ser escrito tem que vir na forma de um qgis.core.QgsField – isso é mais ou menos um encapsulamento de um nome de atributo e seu tipo (PyQt4.QtCore.QVariant)
  • O provedor de dados deve ser capaz de realizar a atribuição ( caps & QgsVectorDataProvider.AddAttributes)
  • QgsVectorLayer.addAttribute – método que retorna um booleano ao invés de lançar uma exceção
from qgis.core import QgsField
from qgis.gui import QgsMessageBar
from PyQt4.QtCore import QVariant


def edit_active_layer(attr_name, attr_type):
    layer = iface.activeLayer()
    caps = layer.dataProvider().capabilities()

    if caps & QgsVectorDataProvider.AddAttributes:
        layer.startEditing()
        if layer.addAttribute(QgsField(attr_name, attr_type)):
            iface.messageBar().pushMessage("Attribute {0} was successfully added to the active layer.".format(attr_name), QgsMessageBar.SUCCESS)
            layer.commitChanges()
        else:
            iface.messageBar().pushMessage("Attribute {0} was not added. Does it already exist?".format(attr_name), QgsMessageBar.CRITICAL)
            layer.rollBack()

edit_active_layer("new_string_attribute", QVariant.String)

3. CRIANDO UMA NOVA CAMADA VETORIAL

É possível criar uma camada vetorial totalmente nova com o console Python. Abaixo, é apresentada uma função muito simples (create_new_layer), mas espero que você possa imaginar as maneiras como ela pode ser ajustada.

from qgis.core import QgsField, QgsFields, QgsVectorLayer, QgsFeature, QgsGeometry, QgsPoint
from PyQt4.QtCore import QVariant

def create_new_layer():
    filename = "/path/to/your/vector/file.gpkg"

    fields = QgsFields()
    fields.append(QgsField("attr1", QVariant.String))
    fields.append(QgsField("attr2", QVariant.Int))

    file = QgsVectorFileWriter(
        filename,
        "UTF8",
        fields,
        QGis.WKBPoint,
        QgsCoordinateReferenceSystem(4326),
        "GPKG"
    )

    layer = QgsVectorLayer(filename, filename.split("/")[-1], "ogr")
    QgsMapLayerRegistry.instance().addMapLayer(layer)

    if not layer.dataProvider().capabilities() & QgsVectorDataProvider.AddAttributes:
        pass

    feature = QgsFeature(layer.pendingFields())
    feature.setGeometry(QgsGeometry().fromPoint(QgsPoint(0, 0)))
    feature.setAttribute("attr1", "attr1")
    feature.setAttribute("attr2", 2)

    layer.startEditing()

    if layer.addFeature(feature, True):
        layer.commitChanges()
    else:
        layer.rollBack()
        iface.messageBar().pushMessage("Feature addition failed.", QgsMessageBar.CRITICAL)

create_new_layer()

Esses foram apenas alguns exemplos do que pode ser feito com a API do QGIS e o console Python. No próximo post, vamos nos concentrar nas associações espaciais dentro do QGIS.

by Fernando Quadro at December 03, 2018 10:30 AM

December 02, 2018

In Movement data in GIS #16, I presented a new way to deal with trajectory data using GeoPandas and how to load the trajectory GeoDataframes as a QGIS layer. Following up on this initial experiment, I’ve now implemented a first version of an algorithm that performs a spatial analysis on my GeoPandas trajectories.

The first spatial analysis algorithm I’ve implemented is Clip trajectories by extent. Implementing this algorithm revealed a couple of pitfalls:

  • To achieve correct results, we need to compute spatial intersections between linear trajectory segments and the extent. Therefore, we need to convert our point GeoDataframe to a line GeoDataframe.
  • Based on the spatial intersection, we need to take care of computing the corresponding timestamps of the events when trajectories enter or leave the extent.
  • A trajectory can intersect the extent multiple times. Therefore, we cannot simply use the global minimum and maximum timestamp of intersecting segments.
  • GeoPandas provides spatial intersection functionality but if the trajectory contains consecutive rows without location change, these will result in zero length lines and those cause an empty intersection result.

So far, the clip result only contains the trajectory id plus a suffix indicating the sequence of the intersection segments for a specific trajectory (because one trajectory can intersect the extent multiple times). The following screenshot shows one highlighted trajectory that intersects the extent three times and the resulting clipped trajectories:

This algorithm together with the basic trajectory from points algorithm is now available in a Processing algorithm provider plugin called Processing Trajectory.

Note: This plugin depends on GeoPandas.

Note for Windows users: GeoPandas is not a standard package that is available in OSGeo4W, so you’ll have to install it manually. (For the necessary steps, see this answer on gis.stackexchange.com)

The implemented tests show how to use the Trajectory class independently of QGIS. So far, I’m only testing the spatial properties though:

def test_two_intersections_with_same_polygon(self):
    polygon = Polygon([(5,-5),(7,-5),(7,12),(5,12),(5,-5)])
    data = [{'id':1, 'geometry':Point(0,0), 't':datetime(2018,1,1,12,0,0)},
        {'id':1, 'geometry':Point(6,0), 't':datetime(2018,1,1,12,10,0)},
        {'id':1, 'geometry':Point(10,0), 't':datetime(2018,1,1,12,15,0)},
        {'id':1, 'geometry':Point(10,10), 't':datetime(2018,1,1,12,30,0)},
        {'id':1, 'geometry':Point(0,10), 't':datetime(2018,1,1,13,0,0)}]
    df = pd.DataFrame(data).set_index('t')
    geo_df = GeoDataFrame(df, crs={'init': '31256'})
    traj = Trajectory(1, geo_df)
    intersections = traj.intersection(polygon)
    result = []
    for x in intersections:
        result.append(x.to_linestring())
    expected_result = [LineString([(5,0),(6,0),(7,0)]), LineString([(7,10),(5,10)])]
    self.assertEqual(result, expected_result) 

One issue with implementing the algorithms as QGIS Processing tools in this way is that the tools are independent of one another. That means that each tool has to repeat the expensive step of creating the trajectory objects in memory. I’m not sure this can be solved.

by underdark at December 02, 2018 04:08 PM

November 30, 2018

Shithole President - DSC07529_ep

Here is a little bit of fun for you to enjoy at a staff social, after your Xmas lunch or in the pub one evening

This is how the Sh*thole Geography Standup Quiz works.

“At the beginning everyone stands up. 

Quizmaster asks a question with 3 suggested answers.

If you think the answer is the first one put your left hand up, if you think it is the second one both hands up, if you think it is the third one put your right hand up. 

QM tells you the correct answer, everyone who got it wrong sit down. If you didn’t make a choice then you also sit down. There are some other interesting stats in the speaker notes for each slide (you need to download the presentation)

Then we go again until one person is left standing – if everyone gets knocked out you can all stand up again and keep answering questions.

There is a tie breaker question at the end”

And you could ignore all my instructions and just have a fun time after Xmas lunch or even do the quiz on your own and see how many questions you can answer, you could tweet your score with the hashtag #ShitholeQuiz

What’s the point of the maps at the end of each slide/question? I’m not sure! The quiz was first presented at FOSS4G with Ken and we had a cartographic spin to the whole talk, I changed it to become a bit more philosophical – maybe the maps disprove some of our preconceptions. 



Don’t press the autoplay button on the quiz or it will go into auto advance mode which is not the ideal way to run the quiz, use the > button to advance and the < to go backwards if needed. If you want to download the quiz or access directly you can find the quiz here

by Steven at November 30, 2018 05:05 PM

This is the sixth progress report of the GDAL SRS barn effort. The pace of changes has not yet slow down, with still a significant part of the work being in PROJ, and an initial integration in GDAL.

The major news item is that RFC2, implementing the new capabilities (WKT-2 support, late-binding approach, SQLite database), has now been merged into PROJ master.

An initial integration of PROJ master into GDAL has been started in a custom GDAL branch . This includes:
  • PROJ master, which will be released as 6.0, is now a required dependency of GDAL. It actually becomes the only required external third-party dependency (if we except the copies of a few libraries, such as libtiff, libgeotiff, etc. that have been traditionaly included into the GDAL source tree)
  • The dozen of continuous integration configurations have been modified to build PROJ master as a preliminary step.
  • Related to the above, we have including into PROJ a way to "version" its symbols. If PROJ is built with -DPROJ_RENAME_SYMBOLS in CFLAGS and CXXFLAGS, all its exported symbols are prefixed with "internal_". This enables GDAL to link against PROJ master, while still using pre-compiled dependencies (such as libspatialite) that link against the system PROJ version, without a risk of symbol clash. This is particularly useful to be able to run GDAL autotests on continuous integration environments that use pre-packaged dependencies (or if you want to test the new GDAL without rebuilding all reverse dependencies of GDAL). This however remains a hack, and ultimately when PROJ 6 has been released, all reverse dependencies should be built against it. (this solution has been successfully tested in the past where GDAL had a libtiff 4.0 internal copy, whereas external libtiff used by some GDAL dependencies relied on the system libtiff 3.X)
  • Compatibility mechanisms which were required to support older PROJ versions have been removed. In particular, the runtime loading (using dlopen() / LoadLibrary() mechanism) has been removed. It proved to cause code complication, and users frequently ran into headaches with different PROJ versions being loaded and clashing/crashing at runtime.
  • The OGRSpatialReference class which implements CRS manipulation in GDAL has been modified to use the new PROJ functions to import and export between WKT and PROJ strings. Previously GDAL had such code, which is now redundant with what PROJ offers. This preliminary integration caused a number of fixes to be made on PROJ to have compatibility with the input and output of GDAL for WKT.1 and PROJ strings. Besides "moving" code from GDAL to PROJ, a practical consequence is that the addition of a new projection method into PROJ will no longer require changes to be made to GDAL for it to be usable for reprojection purposes.

There have been reflections on how to use the new code developped in PROJ by the existing PROJ code. A pull request is currently under review and implements:
  • changes needed to remove from the data/ directory the now obsolete EPSG, IGNF, esri and esri.extra files to rely instead of the proj.db dataase 
  • making the proj_create_crs_to_crs() API use the new late-binding approach to create transformation pipelines
  • updating cs2cs to use that new API. 
  • list and address backward compatibility issues related to honouring official axis order
Integration phase in GDAL continus with the aim of using more of the new PROJ code. Typically the OGRSpatialReference class that models in GDAL the CRS/SRS was up to now mostly a hierarchy of WKT nodes, where setters methods of OGRSpatialReference would directly create/modify/delete nodes, and getter methods query them. This approach was fine when you had to manage just one WKT version (with the caveat that it was also easy to produce invalid WKT representions, lacking mandatory nodes). However, this is no longer appropriate now that we want to support multiple WKT versions. Our goal is to make OGRSpatialReference act rather on osgeo::proj::CRS objects (and its derived classes). Switching between the two abstractions is a non-trivial task and doing it in a bing-bang approach seemed risky, so we are progressively doing it by using a dual internal modelling. A OGRSpatialReference instance will maintain as a primary source a osgeo::proj::CRS object, and for operations not yet converted to the new approach, will fallback to translating it internally to WKT.1 to allow direct manipulation of the nodes, and then retranslate that updated WKT.1 representation back to a osgeo::proj::CRS object. Ultimately the proportion of methods using the fallback way should decrease (it is not completely clear we can remove all of them since direct node manipulation is spread in a significant number of GDAL drivers). The task is slowly progressing, because each change can subtely modify the final WKT.1 representation (nodes being added, number of significant digits changing) and cause a number of unit tests to break (GDAL autotest suite is made of 280 000 lines of Python code) and be analyzed to see if there was a bug and or just an expected result to be slightly altered.
Because of all the above impacts, we have decided to do an early release in December of GDAL master as GDAL 2.4.0 with all the new features since GDAL 2.3, in order to be able to land this PROJ integration afterwards afterwards. A GDAL 2.5.0 release will hopefully follow around May 2019 with the result of the gdalbarn work.


Other side activities regarding collecting transformation grids:
  • Following a clarification from IGN France on the open licensing of their geodesy related resources, their CRS and transformation XML registry is now processed to populate the IGNF objects in the proj.db database (the previous import used the already processed IGNF file containing PROJ string, which caused information losses). The associated vertical shift grids have also been converted from their text-based format to the PROJ digestable .gtx format, integrated in the proj-datumgrid-europe package, and they have been referenced in the database for transformations that use them.
  • The NGS GEOID 2012B vertical grids to convert between NAD83 ellipsoidal heights and NAVD88 heights have also been integrated in the proj-datumgrid-north-america package

by Even Rouault (noreply@blogger.com) at November 30, 2018 02:05 PM

November 29, 2018

O QGIS é uma ferramenta brilhante para automação baseada em Python em forma de scripts personalizados ou até mesmo plugins. Os primeiros passos para escrever o código personalizado podem ser um pouco difíceis, já que você precisa entender a API do Python que é um pouco complexa. A série de Desenvolvimento de Plugins do QGIS que inicia hoje tem como objetivo o desenvolvimento de um plug-in personalizado totalmente funcional capaz de gravar valores de atributos de uma camada de origem para uma camada de destino com base em sua proximidade espacial.

Nesta parte, mencionarei o básico, o que é bom saber antes de começar.

1. Documentação

Diferentes versões do QGIS vêm com diferentes APIs do Python. A documentação deve ser encontrada em https://qgis.org, sendo a mais recente a versão 3.2. Observe que, se você acessar diretamente o site http://qgis.org/api/, verá os documentos atuais.

Alternativamente, você pode o “apt install qgis-api-doc” em seu sistema Ubuntu e rodar “python -m SimpleHTTPServer[port]” dentro de “/usr/share/qgis/doc/api”. Você encontrará a documentação em “http://localhost:8000” (se você não fornecer o número da porta) e estará disponível mesmo quando estiver off-line.

2. Estrutura Básica da API

Abaixo uma visão resumida do que está disponível dentro da API:

  • Pacote qgis.core traz todos os objetos básicos como QgsMapLayer, QgsDataSourceURI, QgsFeature, etc
  • O pacote qgis.gui traz elementos GUI que podem ser usados ​​dentro do QGIS como QgsMessageBar ou QgsInterface
  • qgis.analysis, qgis.networkanalysis, qgis.server e qgis.testing pacotes que não serão abordados na série
  • Módulo qgis.utils que vem com iface (muito útil no console do QGIS Python)

3. Console Python do QGIS

Usar o console Python é a maneira mais fácil de automatizar o fluxo de trabalho do QGIS. Pode ser acessado pressionando Ctrl + Alt + P ou navegando pelo menu em Plugins -> Python Console. Como mencionado acima o módulo iface do qgis.utils é exposto por padrão dentro do console, permitindo-lhe interagir com o QGIS GUI. Experimente os exemplos a seguir, para fazer um teste inicial:

iface.mapCanvas().scale() # retorna a escala atual do mapa
iface.mapCanvas().zoomScale(100) # zoom para escala 1:100 
iface.activeLayer().name() # obtém o nome da camada ativa 
iface.activeLayer().startEditing() # realizar edição

Essa foi uma breve introdução à API do QGIS, no próximo post falaremos mais profundamente sobre o console do QGIS.

by Fernando Quadro at November 29, 2018 11:33 AM

November 28, 2018

A partir do GeoServer 2.14, a saída produzida pelo recurso REST para as solicitações de camadas estão usando um nome de pacote diferente (org.locationtech em vez de com.vividsolutions) para os tipos de geometria devido ao upgrade para o JTS (Java Topology Suite) 1.16.0. Por exemplo:

Antes:

...
<attribute>
  <name>geom</name>
  <minOccurs>0</minOccurs>
  <maxOccurs>1</maxOccurs>
  <nillable>true</nillable>
  <binding><strong>com.vividsolutions.jts.geom.Point</strong></binding>
</attribute>
...

Depois:

...
<attribute>
  <name>geom</name>
  <minOccurs>0</minOccurs>
  <maxOccurs>1</maxOccurs>
  <nillable>true</nillable>
  <binding>org.locationtech.jts.geom.Point</binding>
</attribute>
...

Qualquer cliente REST que dependa dessa informação de ligação deve atualizadar para suportar os novos nomes.

Fonte: GeoServer Documentation

by Fernando Quadro at November 28, 2018 02:05 PM

November 26, 2018

How much winning is enough? Have you been winning so much that you’re tired of winning now?

I ask because last month I gave a talk (PDF Download) to the regional GIS association in Manitoba, about open source and open data. My talk included a few points that warned about the downsides of being beholden to a single software vendor, and it included some information about the software available in the open source geospatial ecosystem.

MGUG Keynote 2018

In a testament to the full-spectrum dominance of Esri, the audience was almost entirely made up of Esri customers. The event was sponsored by Esri. Esri had a table at the back of the room. Before giving my talk, I made a little joke about the fact that my talk would in fact include some digs at Esri (though I left the most pointed ones on the cutting room floor).

People seemed to like the talk. They laughed at my jokes. They nodded in the right places.

Among the points I made:

  • Single-vendor dominance in our field is narrowing the understanding of “what is possible” amongst practitioners in that ecosystem.
  • Maintaining a single-vendor policy dramatically reduces negotiating power with that vendor.
  • Maintaining a single-vendor policy progressively de-skills your staff, as they become dependant on a single set of tooling.
  • Practitioners have higher market value when they learn more than just the tools of one vendor, so self-interest dictates learning tools outside the single-vendor ecosystem.
  • Point’n’click GIS tools from Esri have widened access to GIS, which is a good thing, but driven down the market value of practitioners who limit themselves to those tools.

None of these points is unique to Esri – they are true of any situation where a single tool has driven competitors off the field, whether it be Adobe graphics tools or Autodesk CAD tools or Microsoft office automation tools.

Nor are any of these points indicative of any sort of ill will or malign intent on the part of Esri – they are just the systemic effects of market dominance. It is not contingent on Esri to change their behaviour or limit their success; it’s contingent on practitioners and managers to recognize the negative aspects of the situation and react accordingly.

And yet.

Esri and Winning

Despite the fact that almost all the people in the room were already their customers, that no new business would be endangered by my message, that all the students would still be taught their tools, that all the employers would still include them in job requirements, that people would continue to use the very words they choose to describe basic functions of our profession …

Despite all that, the Esri representative still went to the president of the association, complained to her about the content of my talk, and asked her to ensure that nothing I would say in my afternoon technical talk would be objectionable to himself. (In the event, I made some nasty jokes about Oracle, nobody complained.)

For some of these people, no amount of winning is enough, no position of dominance is safe, no amount of market leverage is sufficient.

It’s sad and it’s dangerous.

I was reminded of this last week, meeting an old friend in Australia and learning that he’d been blackballed out of a job for recommending software that wasn’t Esri software. Esri took away his livelihood for insufficient fealty.

This is the danger of dominance.

When the local Esri rep has a better relationship with your boss than you do, do you advocate for using alternative tools? You could be limiting or even potentially jeapardizing your career.

When Esri has locked up the local geospatial software market, do you bid an RFP with an alternative open tool set? You could lose your Esri partnership agreement and with it your ability to bid any other local contracts. Esri will make your situation clear to you.

This is the danger of dominance.

A market with only one vendor is not a market. There’s a name for it, and there’s laws against it. And yet, our profession glories in it. We celebrate “GIS day”, a marketing creation of our dominant vendor. Our publicly funded colleges and universities teach whole curricula using only Esri tools.

And we, as a profession, do not protest. We smile and nod. We accept our “free” or “discounted” trainings from Esri (comes with our site license!) and our “free” or “discounted” tickets to the Esri user conference. If we are particularly oblivious, we wonder why those open source folks never come around to market their tools to us.

We have met the enemy, and he is us.

We have met the enemy and he is us

November 26, 2018 01:00 PM

November 25, 2018

Last week the first official “FOSS4G/SOTM Oceania” conference was held at Melbourne University. This was a fantastic event, and there’s simply no way I can extend sufficient thanks to all the organisers and volunteers who put this event together. They did a brilliant job, and their efforts are even more impressive considering it was the inaugural event!

Upfront — this is not a recap of the conference (I’m sure someone else is working on a much more detailed write up of the event!), just some musings I’ve had following my experiences assisting Nathan Woodrow deliver an introductory Python for QGIS workshop he put together for the conference. In short, we both found that delivering this workshop to a group of PyQGIS newcomers was a great way for us to identify “pain points” in the PyQGIS API and areas where we need to improve. The good news is that as a direct result of the experiences during this workshop the API has been improved and streamlined! Let’s explore how:

Part of Nathan’s workshop (notes are available here) focused on a hands-on example of creating a custom QGIS “Processing” script. I’ve found that preparing workshops is guaranteed to expose a bunch of rare and tricky software bugs, and this was no exception! Unfortunately the workshop was scheduled just before the QGIS 3.4.2 patch release which fixed these bugs, but at least they’re fixed now and we can move on…

The bulk of Nathan’s example algorithm is contained within the following block (where “distance” is the length of line segments we want to chop our features up into):

for input_feature in enumerate(features):
    geom = feature.geometry().constGet()
    if isinstance(geom, QgsLineString):
        continue
    first_part = geom.geometryN(0)
    start = 0
    end = distance
    length = first_part.length()

    while start < length:
        new_geom = first_part.curveSubstring(start,end)

        output_feature = input_feature
        output_feature.setGeometry(QgsGeometry(new_geom))
        sink.addFeature(output_feature)

        start += distance
        end += distance

There’s a lot here, but really the guts of this algorithm breaks down to one line:

new_geom = first_part.curveSubstring(start,end)

Basically, a new geometry is created for each trimmed section in the output layer by calling the “curveSubstring” method on the input geometry and passing it a start and end distance along the input line. This returns the portion of that input LineString (or CircularString, or CompoundCurve) between those distances. The PyQGIS API nicely hides the details here – you can safely call this one method and be confident that regardless of the input geometry type the result will be correct.

Unfortunately, while calling the “curveSubstring” method is elegant, all the code surrounding this call is not so elegant. As a (mostly) full-time QGIS developer myself, I tend to look over oddities in the API. It’s easy to justify ugly API as just “how it’s always been”, and over time it’s natural to develop a type of blind spot to these issues.

Let’s start with the first ugly part of this code:

geom = input_feature.geometry().constGet()
if isinstance(geom, QgsLineString):
    continue
first_part = geom.geometryN(0)
# chop first_part into sections of desired length
...

This is rather… confusing… logic to follow. Here the script is fetching the geometry of the input feature, checking if it’s a LineString, and if it IS, then it skips that feature and continues to the next. Wait… what? It’s skipping features with LineString geometries?

Well, yes. The algorithm was written specifically for one workshop, which was using a MultiLineString layer as the demo layer. The script takes a huge shortcut here and says “if the input feature isn’t a MultiLineString, ignore it — we only know how to deal with multi-part geometries”. Immediately following this logic there’s a call to geometryN( 0 ), which returns just the first part of the MultiLineString geometry.

There’s two issues here — one is that the script just plain won’t work for LineString inputs, and the second is that it ignores everything BUT the first part in the geometry. While it would be possible to fix the script and add a check for the input geometry type, put in logic to loop over all the parts of a multi-part input, etc, that’s instantly going to add a LOT of complexity or duplicate code here.

Fortunately, this was the perfect excuse to improve the PyQGIS API itself so that this kind of operation is simpler in future! Nathan and I had a debrief/brainstorm after the workshop, and as a result a new “parts iterator” has been implemented and merged to QGIS master. It’ll be available from version 3.6 on. Using the new iterator, we can simplify the script:

geom = input_feature.geometry()
for part in geom.parts():
    # chop part into sections of desired length
    ...

Win! This is simultaneously more readable, more Pythonic, and automatically works for both LineString and MultiLineString inputs (and in the case of MultiLineStrings, we now correctly handle all parts).

Here’s another pain-point. Looking at the block:

new_geom = part.curveSubstring(start,end)
output_feature = input_feature
output_feature.setGeometry(QgsGeometry(new_geom))

At first glance this looks reasonable – we use curveSubstring to get the portion of the curve, then make a copy of the input_feature as output_feature (this ensures that the features output by the algorithm maintain all the attributes from the input features), and finally set the geometry of the output_feature to be the newly calculated curve portion. The ugliness here comes in this line:

output_feature.setGeometry(QgsGeometry(new_geom))

What’s that extra QgsGeometry(…) call doing here? Without getting too sidetracked into the QGIS geometry API internals, QgsFeature.setGeometry requires a QgsGeometry argument, not the QgsAbstractGeometry subclass which is returned by curveSubstring.

This is a prime example of a “paper-cut” style issue in the PyQGIS API. Experienced developers know and understand the reasons behind this, but for newcomers to PyQGIS, it’s an obscure complexity. Fortunately the solution here was simple — and after the workshop Nathan and I added a new overload to QgsFeature.setGeometry which accepts a QgsAbstractGeometry argument. So in QGIS 3.6 this line can be simplified to:

output_feature.setGeometry(new_geom)

Or, if you wanted to make things more concise, you could put the curveSubstring call directly in here:

output_feature = input_feature
output_feature.setGeometry(part.curveSubstring(start,end))

Let’s have a look at the simplified script for QGIS 3.6:

for input_feature in enumerate(features):
    geom = feature.geometry()
    for part in geom.parts():
        start = 0
        end = distance
        length = part.length()

        while start < length:
            output_feature = input_feature
            output_feature.setGeometry(part.curveSubstring(start,end))
            sink.addFeature(output_feature)

            start += distance
            end += distance

This is MUCH nicer, and will be much easier to explain in the next workshop! The good news is that Nathan has more niceness on the way which will further improve the process of writing QGIS Processing script algorithms. You can see some early prototypes of this work here:

So there we go. The process of writing and delivering a workshop helps to look past “API blind spots” and identify the ugly points and traps for those new to the API. As a direct result of this FOSS4G/SOTM Oceania 2018 Workshop, the QGIS 3.6 PyQGIS API will be easier to use, more readable, and less buggy! That’s a win all round!

by Nyall Dawson at November 25, 2018 12:05 AM

November 24, 2018

November 23, 2018

A versão 2.14.1 do GeoServer veio com uma novidade: A página do editor de estilo agora tem um botão de “Tela cheia” no canto superior direito da janela:

Se pressionado, o editor e a visualização serão exibidos lado a lado e usarão todo o espaço da janela do navegador:

A cada atualização a seção de estilos do GeoServer tem melhorado. A equipe de desenvolvimento já a algum tempo tem dado uma atenção especial a essa seção, e já está muito mais fácil lidar com a edição e visualização dos estilo no GeoServer.

by Fernando Quadro at November 23, 2018 10:30 AM

It is important to note something from the very beginning. The interpolated bathymetry developed in this project does not reflect the actual bathymetry of the Wellington Harbour. It is my best guess based on the tools I had and the data I worked with. Furthermore, this interpolation is NOT the official product of any institution. It is an interpolation created by me only for the purposes of visualization.

welly_harbour-colour-and-aerial_FULLVIEW

Part of the goal when visualizing the Wellington landscape was to incorporate a better idea about what may be happening below the surface of the harbor. Various bathymetric scans in the past have gathered much of the information and institutions like NIWA have done the work visualizing that data. As for myself, I did not have access to those bathymetries; however, I did have a sounding point data set to work with, so I set about interpolating those points.

The data set, in CSV format, was over a million points; too dense for a single interpolation. I worked out a basic plan for the interpolation based on splitting the points into a grid, interpolate the smaller bits, then reassemble the grid tiles into a uniform bathymetry.

Conversion from CSV to shp
Using the open option (-oo) switch, OGR will convert CSV to shp seamlessly

ogr2ogr -s_srs EPSG:4167 -t_srs EPSG:4167 -oo X_POSSIBLE_NAMES=$xname* -oo Y_POSSIBLE_NAMES=$yname*  -f "ESRI Shapefile" $outputshapepath/$basenme.shp $i

Gridding the Shapefile
With the shapefile in place, I next needed to break it into smaller pieces for interpolation. For now, I create the grid by hand in QGIS using the ‘Create Grid’ function. This is found under Vector>Reasearch Tools>Create Grid. Determining a grid size that works best for the interpolation is a bit of trial and error. You want the largest size your interpolation can manage without crashing. Using the grid tool from QGIS in very convenient, in that it creates an attribute table of the xmin, xmax, ymin, ymax corrodinates for each tile in the grid. These attributes become very helpful during the interpolation process.

Interpolating the Points
I switched things up in the interpolation methods this time and tried out SAGA GIS. I have been looking for a while now for a fast and efficient method of interpolation that I could easily build into a scripted process. SAGA seemed like a good tool for this. The only drawback, I had a very hard time finding examples online about how to use this tool. My work around to was to test the tool in QGIS first. I noticed when the command would run, QGIS saved the last command in a log file. I found that log, copied out the command line function, and began to build my SAGA command for my script from there.

Here is look at the command I used:


saga_cmd grid_spline "Multilevel B-Spline Interpolation" -TARGET_DEFINITION 0 -SHAPES "$inputpoints" -FIELD "depth" -METHOD 0 -EPSILON 0.0001 -TARGET_USER_XMIN $xmin -TARGET_USER_XMAX $xmax -TARGET_USER_YMIN $ymin -TARGET_USER_YMAX $ymax -TARGET_USER_SIZE $reso -TARGET_USER_FITS 0 -TARGET_OUT_GRID "$rasteroutput/sdat/spline_${i}"

I tested a number of methods and landed on ‘grid_spline’ as producing the best results for the project. It was useful because it did a smooth interpolation across the large ‘nodata’ spaces.

Once the initial interpolation was complete, I needed to convert the output to GeoTIFF since SAGA exports in an .sdat format. Easy enough since GDAL_TRANSLATE recognizes the .sdat format. I then did my standard prepping and formatting for visualization:


gdal_translate "$iupput_sdat/IDW_${i}.sdat" "$output_tif/IDW_${i}.tif"
gdaldem hillshade -multidirectional -compute_edges "$output_tif/IDW_${i}.tif" "$ouput_hs/IDW_${i}.tif"
gdaladdo -ro "$output_tif/IDW_${i}.tif" 2 4 8 16 32 64 128
gdaladdo -ro "$ouput_hs/IDW_${i}.tif"2 4 8 16 32 64 128

Here is look at the interpolated harbour bathymetry, hillshaded, with Wellington 1m DEM hillshade added over top
welly_harbour_bw_all

And here is a look at the same bathy hillshade with coloring
welly_harbour_bw-and-aerial

Visualizing the Bathymetry
With the bathymetry, complete it was simply a matter of building it into the existing visualization I built for the Wellington Region. Learn more about the project here. The visualization was four steps:

Hillshade
addedbathy_bathyonlypng
Color
addedbathy_bathyonly_withcolor
Aerial Imagery
addedbathy_bathyonly_withcoloraerial
Then merge the models together
addedbathy_final

Easy as, eh? Let me know what you think!

Note: All imagery was produced during my time at Land Information New Zealand. Imagery licensing can be found here:
“Source: Land Information New Zealand (LINZ) and licensed by LINZ for re-use under the Creative Commons Attribution 4.0 International licence."

by xycarto at November 23, 2018 04:39 AM

November 22, 2018

As interest in LiDAR derived elevation increases, so grows the interest in the capabilities. LiDAR derived elevation data has been great for my visualization game and in helping me communicate the story out about what LiDAR can do. It all starts with a picture to get the imagination going.

wellyvation

The Wellington model derived for this project is part of an ongoing project to help increase the exposure of the Wellington 1m DEM/DSM elevation data derived from LiDAR. Step one for me is getting a working model built in QGIS, capturing still images, and increasing interest in the data.

I’ve talked about the processing of the elevation data for Wellington visualizations in the past, so for this post I’m only focusing on the blending of the data sets in building the model. This project is a good model since it encompasses a number of subtle techniques to get the model to stand out. This post is one of a two part series; the second post discusses the techniques used to derive and visualize the bathymetry for the surrounding harbor.

Let’s start with the base, Aerial Imagery.
wellyhabour_aerialonly

Blended with a hillshade
wellyhabour_aerial_withHS

DSM added for texture and context
wellyhabour_aerial_withDSMHS

Slope added to define some edges
wellyhabour_aerial_withDSMDEMSLOPEHS

Some darker shading added to the bathymetry to frame the elevation data
wellyhabour_aerial_withDSMDEMSLOPEHS_darkenframe

And finally some added bathymetry to lighten the edges at the shoreline enhancing the frame a bit more.
wellyhabour_aerial_withDSMDEMSLOPEHS_edgeframe

In the end there is some post-processing in Photoshop to lighten up the image. Honestly, this could have been done in QGIS, but I was being lazy. For the images produced, there was no need to retain the georeferencing, and when that is the case, I rely on Photoshop for color and light balancing.

The greatest difficultly in this project so far has been trying to create a universal model for the data set. I’m finding that as I visualize different regions using this model, I need to adjust the hillshading quite significantly to draw out different features. Take a look at the images here. It is the same model, but with the noticeably different gradients used in the hillshades. The techniques used for the images in this post worked well for the urban region shown, but fall apart as you move further out into the more mountainous regions. Much of the blending is too harsh and turns the mountains into a black muddled mess. I am almost there, but like any project, it takes a good bit of subtle tweaking of the blending to get a universal image to work.

The entire base mapping work is completed in QGIS. The elevation data was processed using GDAL and the bathymetric interpolations were produced SAGA GIS. There are no color palettes for this project. The aerial imagery does all the work in that department.

Base data can be found here:
DEM: https://data.linz.govt.nz/layer/53621-wellington-lidar-1m-dem-2013/
DSM: https://data.linz.govt.nz/layer/53592-wellington-lidar-1m-dsm-2013/
Aerial Imagery: https://data.linz.govt.nz/layer/51870-wellington-03m-rural-aerial-photos-2012-2013/

The next post covers the development of the bathymetry for the surrounding harbor. Thanks for having a look and let me know what you think.

Note: All imagery was produced during my time at Land Information New Zealand. Imagery licensing can be found here:
“Source: Land Information New Zealand (LINZ) and licensed by LINZ for re-use under the Creative Commons Attribution 4.0 International licence.”

by xycarto at November 22, 2018 10:21 PM

O GeoServer adicionou suporte a adição de dimensões específicas para camadas WMS, conforme especificado nos padrões WMS 1.1.1 e WMS 1.3.0. Existem duas dimensões pré-definidas nos padrões WMS: TIME e ELEVATION. A ativação das dimensões para uma camada permite que os usuários as especifiquem como parâmetros extras em solicitações GetMap, úteis para criar mapas ou animações a partir de dados multidimensionais.

Essas configurações podem ser ativadas e configuradas na Aba “Dimensões”:

Para cada dimensão ativa, as seguintes opções de configuração estão disponíveis:

  • Atributo – Atribua o nome para escolher o valor para esta dimensão (somente vetor). Isso é tratado no início do intervalo se o atributo final também for fornecido.
  • Atributo final – Atribua o nome para escolher o final do intervalo de valores para essa dimensão (opcional, somente para vetores).
  • Apresentação – Tipo de apresentação para os valores disponíveis no documento de recursos.
  • Valor padrão – Valor padrão a ser usado para essa dimensão, se nenhuma for fornecida com a solicitação. Selecione uma das quatro estratégias:
    • Menor valor de domínio – usa o menor valor disponível dos dados
    • Maior valor de domínio – usa o maior valor disponível a partir dos dados mais próximo do valor de referência – Seleciona o valor de dados mais próximo do valor de referência fornecido
    • Valor de referência – tenta usar o valor de referência fornecido como está, independentemente de estar realmente disponível nos dados ou não.
  • Valor de referência – O especificador de valor padrão. Exibido apenas para as estratégias de valor padrão onde é usado.
  • Correspondente mais próximo – Permitir, ou não, suporte ao correspondente mais próximo do WMS nesta dimensão. Atualmente suportado apenas na dimensão de tempo.
  • Intervalo aceitável – uma distância máxima de pesquisa do valor especificado (disponível somente quando o correspondente mais próximo estiver ativado). Pode ser vazio (sem limite), um único valor (pesquisa simétrica) ou usado para especificar um intervalo de pesquisa assimétrica. As distâncias de tempo devem ser especificadas usando a sintaxe do ISO. Por exemplo, PT1H/PT0H permite pesquisar até uma hora antes do valor especificado pelo usuário, mas não depois.

Para dimensão de tempo, o valor deve estar no formato ISO 8601 DateTime (yyyy-MM-ddThh:mm:ss.SSSZ). Para dimensão de elevação, o valor deve ser e inteiro (ponto flutuante).

Somente para a estratégia “Valor de referência”, é possível usar intervalos de tempos e intervalos de elevação, no formulário fromValue/toValue. Somente para a estratégia “valor de referência”
também é possível usar tempos relativos como P1M/PRESENT, mas é preciso ter cuidado para que o valor de referência seja copiado integralmente no documento de recursos e, como resultado, nem todos os clientes estejam reconhecendo essa sintaxe.

Fonte: Blog do GeoServer

by Fernando Quadro at November 22, 2018 02:07 PM

Sometimes there is simply not enough room for all the ideas. Sometimes you want all the images to make it to the final round.

wairarapa

In a recent project to promote some of our elevation data, I was asked to present a number of ideas for a 2000mm x 900mm wall hanging. The piece was to act as a conversation starter and demonstrate some of the finer details elevation from LiDAR possesses.

In the end, the image above was the chosen candidate. Below are the drafts I initially presented for review. You can see the difference in treatment from the original ideas to the final product. Personally, I really enjoyed the images developed for the draft series, I liked the silvery undertones, and I thought it was a shame to merely let these images sit on my hard drive.
Below, you’ll find a brief description about a few challenges faced in the image development.

near_lake_ferry
nice_farm
masterton_region
random
draft_wairarapa

Artifacts and Finer Details
The hardest part of this job was drawing out the finer details of the chosen location. There was a strong interest in showing the ancient river bed; however, without a good bit of tweaking in the hillshades, the image is quite flat. After some trial and error, I found I could get a good contrast by limiting the hillshade values range to 170-190. That’s it, but the readability of the project really hinged on the simple tweak. It really made the details stand out.
That said, the gain in detail also revealed a significant artifact in the data. If you go back up and have a closer look, you will find diagonal depressions running across the images in equal intervals. These are lines from where the LiDAR scans overlap. I haven’t quite had the time to figure out how to remove these from the original data source, so for now I leave them in as conversational piece around improving LiDAR capture practices.
As usual, all map layout work was completed on QGIS, with the bulk of the data processing done using GDAL. The ‘Reject’ images for this post are direct exports from QGIS, with no manipulation apart from some down-sampling and cropping in Photoshop.

Base data can be found here:
DEM: https://data.linz.govt.nz/layer/53621-wellington-lidar-1m-dem-2013/
DSM: https://data.linz.govt.nz/layer/53592-wellington-lidar-1m-dsm-2013/
Aerial Imagery: https://data.linz.govt.nz/layer/51870-wellington-03m-rural-aerial-photos-2012-2013/

I produced a public repository for some of the scripting work. This repository is not specific to the above project but does contain some of the base processing I did on the Wellington elevation data: https://github.com/IReese/wellyvation/tree/master/utils
Hope you like and thanks for checking in!

Note: All imagery was produced during my time at Land Information New Zealand. Imagery licensing can be found here:
“Source: Land Information New Zealand (LINZ) and licensed by LINZ for re-use under the Creative Commons Attribution 4.0 International licence.”

by xycarto at November 22, 2018 03:46 AM

The PostGIS development team is pleased to provide bug fix 2.2.8 for the 2.2 stable branch.

This is the End-Of-Life and final release for PostGIS 2.2 series.

We encourage you to upgrade to a newer minor PostGIS version. Refer to our Version compatibility and EOL Policy for details on versions you can upgrade to.

This release supports PostgreSQL 9.1-9.6.

2.2.8

Continue Reading by clicking title hyperlink ..

by Regina Obe at November 22, 2018 12:00 AM

November 20, 2018

We are happy to announce the release of GeoServer 2.14.1. Downloads are provided (zip|war|exe) along with docs (html|pdf) and extensions.

This is a stable release of the GeoServer 2.14 series and is recommended for all production systems. Users of prior releases of GeoServer are encouraged to upgrade.

This release is made in conjunction with GeoTools 20.1 and GeoWebCache 1.14.1. Thanks to all who contributed to this release.

For more information please see our release notes (2.14.1|2.14.0|2.14-RC).

Improvements and Fixes

This release includes a number of new features and improvements:

  • New coordinate formatting options for WFS layers
  • REST API granule management remove of metadata or all
  • Coverage view support for indexed color model
  • Check handling of WCS 2.0 time/elevation/range subsetting
  • WFS 1.1.0 handling of gml:id
  • WFS Shapefile and GeoJSON output now support geometry with measures
  • Fixes to the start.bat and shutdown.bat scripts on windows

About GeoServer 2.14 Series

Additional information on the GeoServer 2.14 series:

by jgarnett at November 20, 2018 11:32 PM

I was invited to deliver a keynote last week at KortDage to an audience of nearly 800 Danish (and Scandinavian) GI professionals. There were just a few snags:

  • The person who invited me said “Last year Jack Dangermond gave a keynote, this year we wanted something different”. No challenge there!
  • The slot was at 9.00am on the final morning after the delegates had been up till 1.30am boogying
  • I don’t speak Danish and I wasn’t sure how my dry (I’d like to think) Brit humour would go down

So they wanted something different, they liked my #FAKEMAPS talk, I didn’t have a lot of time to come up with something completely new so I decided to re-invent Sh*thole Geography.

Ken Field and I had done a double act at FOSS4G in Dar es Salaam around Donald Trump’s opinion that some countries were “shithole countries” whose citizens were not welcome in the US. We had riffed on the “Orange Clown” as Ken likes to call 45, we had played with UN Sustainable Development Goal stats, Ken gave a brief cartography master class on making global maps and I had created a pub style geography quiz. I could work with that and switch the focus to make a slightly different message for this audience (with apologies to Ken) – a map may not always be the best way to present global statistics.

They didn’t record the whole talk so I can’t share that with you but you can get the drift of the points I was making from this short interview that the organisers did with me after my talk.

Kortdage 2018 – Kort fortæller ikke altid sandheden from Geoforum on Vimeo.

At the end of the talk I offered Sh*thole Geography badges and stickers to the attendees in return for donations to the FOSS4G Travel Grant Programme – the audience were amazingly generous and we raised almost $500

Apart from my talk I also got to meet Anna Webber, an artist who had made an “earth map” of Denmark

You can read more about her map and why she made it on Ken’s and my Mappery site.

Thanks to the organisers for inviting me to speak, thanks to all the people who laughed at my jokes and made me feel welcome. KortDage was a great event.

 

by Steven at November 20, 2018 08:18 PM

Os hacemos llegar la invitación al primer evento organizado por la Red JUST-SIDE, de la que forma parte la Asociación gvSIG. Esperamos sea de vuestro interés (si podéis asistir…allí nos veremos!):

El Departamento de Geografía de la Facultad de Ciencias (UdelaR) tiene el agrado de invitarle al primer congreso de la red JUST-SIDE (Justicia y Sostenibilidad en el Territorio a través de las Infraestructuras de Datos Espaciales) a realizarse en el día 22 de noviembre de 2018 entre las 14 y 18 horas; el mismo abordará la temática de las Tecnologías Libres y contará con expositores nacionales y extranjeros.

Nuestra institución integra esta red de universidades y empresas de Argentina, Brasil, Chile, Costa Rica, España, México, Portugal y Uruguay que, coordinados por la Universidad de Coimbra (Portugal), está llevando adelante un proyecto que vincula el derecho ambiental y territorial con el acceso a la información geográfica y el desarrollo de las Infraestructuras de Datos Espaciales.

La red JUST-SIDE integra investigadores con experiencia en las áreas del derecho, ciencias sociales y tecnologías de información geográfica y busca crear una metodología basada en una Infraestructura de Datos Espaciales como apoyo a la toma de decisiones, promoviendo y fortaleciendo las políticas públicas para hacer frente a los desafíos sociales, ambientales, económicos, jurídicos y democráticos. Está iniciativa está financiada por CYTED (Programa Iberoamericano de Ciencia y Tecnología para el Desarrollo), y estudiará 16 casos concretos en territorios para la mejoría de la eficacia y justicia de las políticas públicas con incidencia territorial.

Quienes estén interesados en asistir les solicitamos realizar su registro previo a través del siguiente enlace, dado que el cupo es limitado; la actividad se desarrollará en el Hotel Dazzler (Salón Laureles), calle 21 de setiembre 2752 esquina Luis de la Torre.

Por favor realizar su registro

Se adjunta programa de la jornada.

– DEPARTAMENTO DE GEOGRAFÍA

by Alvaro at November 20, 2018 04:28 PM

Ya se han publicado las presentaciones realizadas en las 14as Jornadas Internacionales gvSIG, que se celebraron del 24 al 26 de octubre en Valencia (España).

También está disponible la grabación de las mismas y de algunos de los talleres que se impartieron. Los vídeos se encuentran disponibles en su idioma original, habiendo presentaciones y talleres en español e inglés.

Los talleres de los cuales está disponible la grabación para poder seguirlos fueron los de “gvSIG aplicado a Geología” y “Generación de informes con gvSIG Desktop“, ambos en español, y el de “Environmental modelling using gvSIG and the HortonMachine” en inglés.

Cabe destacar que el taller de Informes es la primera documentación disponible del plugin publicado hace unos días sobre la nueva versión gvSIG 2.5 que permite crear informes de forma automática en gvSIG Desktop. ¡No os lo perdáis!

Si no pudiste asistir a las jornadas ahora puedes disponer de la grabación de las distintas sesiones, y aparte de un buen material didáctico gratuito con los talleres.

by Mario at November 20, 2018 12:16 PM

Hoje vamos acessar e consultar o catálogo pycsw do GeoNode a partir de um cliente desktop, neste caso será o QGIS. Os printscreens foram gerados usando o QGIS 2.14 LTR, mas as versões seguintes devem ser semelhantes.

Em primeiro lugar, clique no menu Web e, em seguida, em MetaSearch > MetaSearch

Agora clique no botão Novo e preencha o formulário da seguinte forma:

Nome: GeoNode CSW
URL: http://localhost:8000/catalog/csw?

Clique no botão Informações do serviço e a identificação do serviço CSW deve aparecer na janela principal do MetaSearch:

Agora, clique na guia Pesquisar e tente uma pesquisa básica clicando no botão Pesquisar. Todos os registros são apresentados:

Se você clicar duas vezes em uma das camadas, verá ver as informações do registro:

Você também pode ver o pedido GetRecords realizado pelo pycsw clicando no botão “Ver pesquisa como XML”

Experimente refazer inserindo parâmetros diferentes para realizar consultas mais avançadas:

Hoje ficamos por aqui! Bons estudos!

Fonte: Paolo Corti

by Fernando Quadro at November 20, 2018 10:30 AM

Quando temos nossa área de estudo, muitas vezes realizamos procedimentos de recorte para que todos elementos fiquem dentro desse limite.

Entretanto, em alguns momentos, é interessante que esse recorte não seja realizado exatamente nos limites da área de estudo. Queremos manter a forma do polígono ou linha que cruza nossa área de estudo.

Como podemos realizar essa cruzamento entre polígonos ou linhas com a nossa área de estudo?

Neste tutorial, iremos utilizar os shapefiles dos títulos minerários do estado de Santa Catarina (disponível no site da Agência Nacional de Mineração) e o shapefile das rodovias federais (disponível no site do Departamento Nacional de Infraestrutura e Transporte) para realizar esse procedimento.

Ambos podem ser baixados nos links abaixo:

  • Títulos Minerais: Para baixar, vá no mapa no fim da página e selecione Santa Catarina, em seguida, clique em SHP;
  • Rodovias Estaduais: Procure pelo shapefile do mapa rodiviário.

As rodovias federais podem ser baixadas no site do DNIT.

E vamos verificar quais títulos e rodovias cruzam a nossa área de estudo fictícia: Uma área circular com ponto central nas coordenadas SIRGAS UTM  700.731 / 7.058.005 e raio de 500 metros.

Leia também: Como gerar buffers no ArcGIS.

Lembre-se que para gerar buffers no QGIS, vá em Vetor (Vector) > Ferramentas de Geoprocessamento (Geoprocessing Tools) > Buffer.

Extraindo Shapefiles Sobrepostos no QGIS

Após baixar os shapefiles e criar a área de estudo fictícia no QGIS 3.2, iremos utilizar a ferramenta Seleção por Localização (Select by Location), a qual esta disponível em Vetor (Vector) > Ferramentas de Pesquisa (Research Tools).

Ao clicar nela, a janela abaixo será aberta.

Janela da Ferramenta Select by Location e Área de Estudo ao Lado.Janela da Ferramenta Select by Location e Área de Estudo ao Lado.

Note que a nossa área de estudo (preenchida em vermelho) cruza com vários polígonos dos títulos minerários (linhas em preto) e com essa ferramenta, iremos separar esses polígonos (sem cortá-los, deixando-os inteiros).

Na ferramenta Select by Location, o primeiro item a ser inserido é o shapefile contendo os polígonos a serem selecionados (neste caso, os títulos minerários), em seguida, selecionamos qual tipo de operação (interseção) e baseada em quem essa operação irá ocorrer (área de estudo).

O ultimo item indica que o resultado deverá ser uma nova seleção. Veja que o resultado, apresentado abaixo, são todos os polígonos que “tocam” nossa área de estudo.

Polígonos selecionados encontram-se em amarelo.Polígonos selecionados encontram-se em amarelo.

Cabe lembrar que o processo não termina aqui. Agora precisamos salvar o resultado como shapefile, pois o que temos é apenas uma seleção.

Para salvar a seleção, clique sobre o shapefile com os itens selecionados (i.e. títulos minerários), vá em exportar (export), e clique em salvar feição como (save feature as).

Na nova janela, preencha os dados relacionados à localização do arquivo final, sistema de coordenadas e não se esqueça de marcar o item Salvar Apenas as Feições Selecionadas (Save only selected features), conforme figura abaixo.

Exportando polígonos selecionados como shapefile no QGIS.Exportando polígonos selecionados como shapefile no QGIS.

Pronto! Você agora tem um novo shapefile com todos os títulos minerários “completos” que cruzam com a nossa área de estudo.

Extraindo Shapefiles Sobrepostos no ArcGIS

Após baixar e abrir os arquivos dos títulos minerários e da área de estudo, no ArcToolbox, vá em Data Management Tools > Layers and Table Views e dê dois cliques em Select Layer by Location.

Na janela que abrir, no campo “Input Feature Layer”, selecione o item que terá os polígonos extraídos (neste caso, os títulos minerários), em “Relationship (optional)”, você escolherá qual o processo a ser adotado (aqui, usaremos a interseção), “Selecting Features (optional)” será nossa área de estudo e por fim, em “Selection type (optional)” indica qual é o tipo de seleção que irá ocorrer (manteremos como nova seleção – New_Selection).

Ferramenta para Selecionar Feições pela localização no ArcGIS.Ferramenta para Selecionar Feições pela localização no ArcGIS (e polígonos utilizados).

O resultado desta operação será a seleção dos títulos minerários que cruzam com a nossa área de estudo. A figura abaixo mostra os polígonos selecionados.

Polígonos que tocam nossa área de estudo foram selecionados (em azul claro).Polígonos que tocam nossa área de estudo foram selecionados (em azul claro).

Lembre-se que isto é apenas uma seleção. Precisamos agora exportar o resultado para termos um shapefile novo.

Para realizar esse processo, clique sobre o shapefile com os polígonos selecionados (i.e. Títulos Minerários) e vá em Data > Export Data. Na nova janela, você manterá o primeiro item (“Export:”) como “Selected features” e irá definir o local onde o novo shapefile será salvo.

O menu “Export:” define quem irá ser salvo, neste caso, ao marcar “Selected Features”, iremos exportar somente os arquivos selecionados.

Janela onde marcamos quais itens exportar e onde o shapefile será salvo.Janela onde marcamos quais itens exportar e onde o shapefile será salvo.

E dessa forma, você terá os títulos minerários que cruzam a sua área de estudo.

Usando PyQGIS para Selecionar e Exportar Shapefiles

Antes de começar a escrever, abra o console Python no QGIS 3.x clicando em Plugins > Python Console. Após abrir o console, clique em “Show Editor” para abrir o editor.

Neste exemplo, vamos  utilizar um shapefile diferente, utilizaremos as rodovias estaduais ao invés dos títulos minerários.

O código abaixo representa todo o procedimento que fizemos antes manualmente e após o código, explicamos os comandos utilizados.

# -*- coding: utf-8 -*-

# Carregando pacotes no Python
import processing
import sys
import osgeo.ogr as ogr
import osgeo.osr as osr

# Carregando nossos arquivos shapefile e criando saída
rod_est = "C:/Users/ferna/Desktop/B2E/Rodovias_SC.shp"
area_estudo = "C:/Users/ferna/Desktop/B2E/area_estudo.shp"
saida = "C:/Users/ferna/Desktop/B2E/rod_areaEst.shp"

# Abringo arquivos no QGIS
iface.addVectorLayer(rod_est, "Rodovia Estadual", "ogr")
iface.addVectorLayer(area_estudo, "Area de Estudo", "ogr")

# Selecionando rodovias que cruzam a área de estudo
# Documentação: processing.algorithmHelp('qgis:selectbylocation')
param_Sel = {'INPUT': rod_est, 'PREDICATE': 0,'INTERSECT': area_estudo, 'METHOD': 0}
processing.run('qgis:selectbylocation', param_Sel)
param_Save = {'INPUT': rod_est, 'OUTPUT': saida}
processing.run('qgis:saveselectedfeatures', param_Save)

# Carregando resultado no QGIS
iface.addVectorLayer(saida, "Rodovia", "ogr")

Na lista abaixo, explicamos as principais funções que utilizamos, de modo que você possa aplicar o código aos seus arquivos.

  • iface.addVectorLayer( [Local do Shapefile] , [Nome] , “ogr”): Adiciona e abre o shapefile ao QGIS;
  • processing.run( [Algoritmo para ser Rodado] , [Dicionário com os Parâmetros]).

Cabe lembrar que o comando processing.run() é diferente no QGIS 2.18, sendo definido como processing.runalg() e recebe argumentos diferentes.

Após rodar o nosso código, você obterá quais rodovias estaduais cruzam a nossa área de estudo.

Usando ArcPy para Selecionar e Exportar Shapefiles

No ArcGIS 10.x, clique em “Geoprocessing” > “Python”, isso irá abrir o terminal Python do ArcGIS.

O ArcGIS tem pequeno editor de python integrado ao software, nossa sugestão é que você trabalhe inicialmente em um editor de texto externo (e.g. NotePad++) e depois cole o código no terminal.

Nesta parte, iremos utilizar as rodovias estaduais que mostramos lá no começo, ao invés dos títulos minerários.

O código para executar a extração das rodovias que cruzam nossa área de estudo é apresentado abaixo.

# -*- coding: utf-8 -*-

# Carregando pacotes no Python
import arcpy

# Nossas variáveis
rod_est = "C:\\Users\\ferna\\Desktop\\B2E\\Rodovias_SC.shp"
area_estudo = "C:\\Users\\ferna\\Desktop\\B2E\\area_estudo.shp"
saida = "C:\\Users\\ferna\\Desktop\\B2E\\rod_areaEstArc.shp"

# Abringo arquivos no QGIS
mxd = arcpy.mapping.MapDocument("CURRENT") # Define qual projeto estamos trabalhando
dataFrame = mxd.activeDataFrame # Define o dataframe que estamos trabalhando
camada_ae = arcpy.mapping.Layer(area_estudo)

arcpy.mapping.AddLayer(dataFrame, camada_ae, "AUTO_ARRANGE") # Adiciona Camada

# Selecionando rodovias que cruzam a área de estudo
arcpy.MakeFeatureLayer_management(rod_est, "Rodovias1")
arcpy.SelectLayerByLocation_management("Rodovias1", "intersect", area_estudo)
arcpy.CopyFeatures_management("Rodovias1", saida)

As funções que utilizamos são explicados na lista abaixo:

  • arcpy.mapping.MapDocument(“CURRENT”): Define como projeto padrão o projeto aberto;
  • mxd.activeDataFrame: Define como data frame a ser utilizado o data frame aberto;
  • arcpy.mapping.Layer(): Transforma o caminho com o shapefile em uma camada;
  • arcpy.mapping.AddLayer( [Data Frame] , [Camada] , “AUTO_ARRANGE”): Adiciona camada à tabela de conteúdo (abre o arquivo);
  • arcpy.MakeFeatureLayer_management( [Shapefile], [Arquivo Temporário]): Torna a camada selecionada como principal;
  • arcpy.SelectLayerByLocation_management( [Arquivo Temporário], [Método], [Shapefile para Cruzamento]): Realiza procedimento para selecionar arquivos que se cruzam;
  • arcpy.CopyFeatures_management([Arquivo Temporário], [Saída]): Salva os itens selecionados no caminho especificado.

E com isso, você terá as rodovias que cruzam nossa área de estudo.

Ficou com alguma dúvida? Utilize a seção de comentários e caso esse tutorial tenha te ajudado, compartilhe ele na sua rede social.

by Fernando BS at November 20, 2018 06:07 AM

November 19, 2018

Thanks to your donations, we were able to hire core developers to focus on solving Mac OS specific issues for QGIS. More than 30 MacOS QGIS users donated a little more than 3000 € for this bug fixing round.

After an effort of triage and testing, here is what has been achieved:

Unfortunately, some issues remain. Mainly, the text being rendered as outlines in PDF export (https://issues.qgis.org/issues/3975) remains for now. It might be fixed in a following effort.

Thanks to all donors who helped in this effort and to Denis Rouzaud as a core developer who spent a lot of time investigating and fixing these issues!

by Andreas Neumann at November 19, 2018 08:24 PM

En los últimos años la integración de las tecnologías de la información y la comunicación (TIC) en la gestión urbana han llevado a popularizar términos como el de ‘Smart City’ o ‘Ciudad Inteligente’. Un término en muchas ocasiones utilizado meramente como marketing y vacío de contenido. Desde la Asociación gvSIG siempre hemos defendido e impulsado la idea de que las ciudades sólo puede ser ‘inteligentes’ si se tienen políticas definidas en relación a la soberanía tecnológica y la sostenibilidad, sólo alcanzables con la adopción de tecnologías libres.

Hoy os traemos unos ejemplos de cómo las soluciones en software libre de la Asociación gvSIG mejoran la gestión municipal y pueden llegar a convertirse en herramientas imprescindibles en el día a día de un Ayuntamiento, independientemente de su tamaño.

En primer lugar el arquitecto Nacho Muñoz-Motilla nos cuenta la experiencia del Ayuntamiento de La Pobla de Vallbona, en ‘Creación de una IDE de gestión municipal con gvSIG Online en tiempo récord

¿Pueden los pequeños ayuntamiento sumarse a la modernización que proponen las Smart Cities o han de quedar fuera? Pepe casado nos habla de la experiencia del Ayuntamiento de Villarcayo de Merindad de Castilla la Vieja en ‘gvSIG Online, como crear una IDE en un pequeño ayuntamiento

Por último Antonio García Benlloch nos cuenta como el Ayuntamiento de Bétera está combinando el uso de distintos productos de la Suite gvSIG en ‘Captura de datos de campo con gvSIG Mobile, edición con gvSIG Desktop y publicación web en el Geoportal del Ayuntamiento de Bétera

by Alvaro at November 19, 2018 11:10 AM

Não há como negar que cidades inteligentes (Smart Cities) é um assunto da moda, e que muito tem se falado nisso no Brasil! Mas a pergunta que eu gostaria de lhe fazer é: Sua cidade pode ser considerada uma Smart City?

Segundo uma publicação da Juniper Research em 2017 “Uma cidade inteligente é caracterizada pela integração da tecnologia em uma abordagem estratégica para a sustentabilidade, o bem-estar dos cidadãos e o desenvolvimento econômico.”

Neste post, explorarei preceitos e visões comuns sobre o que é uma cidade inteligente, e no decorrer do post, você terá condições de responder minha pergunta inicial.

Uma cidade muitas vezes ganha seu status de “inteligente” quando processos específicos, como gerenciamento de informações e comunicações, se interconectam e usam tecnologias avançadas, como IoT (Internet of Things: dispositivos físicos conectados uns com os outros e com a internet) para melhorar suas operações e serviços. Esses serviços geralmente são baseados em automação e tecnologias inteligentes para gerenciar serviços públicos, como energia, abastecimento de água e coleta de lixo.

1. Como medimos se uma cidade é inteligente?

O tópico de como identificar ou medir como uma cidade inteligente é amplamente debatido, com muitas organizações fornecendo uma lista definitiva de critérios ou métricas “inteligentes” para as cidades. Aqui estão alguns exemplos de CITYkeys, European Smart Cities e Lendlease.

Neste blog, usaremos os critérios de um paper publicado pela Juniper Research em 2017 para medir o quão inteligente é uma cidade. No paper, a Juniper Research estabeleceu um sistema único de pontuação para analisar e avaliar a “inteligência” das cidades. A equipe mede a atividade de cada cidade observando os seguintes pontos de dados:

  • Transportes: Quão conectados e eficientes são os serviços? A cidade coleta dados do monitoramento de tráfego em tempo real e usa esses dados para informar os ajustes de fluxo de tráfego e sinal, com base nos requisitos de resposta a emergências?
  • Saúde: Quão inovadora e impactante é a abordagem dos serviços? A cidade tem regulamentos de emissão de ar e soluções de transporte saudáveis?
  • Segurança pública: Como a tecnologia impacta a cidade para a segurança pública? A iluminação pública inteligente foi implantada? A análise inteligente de vigilância por vídeo ou software de crime preditivo e de risco de incêndio estão sendo usados?
  • Produtividade: Quão colaborativo e co-criativo é a estratégia inteligente da cidade? Eles estão organizando conferências e hackathons para reunir diferentes partes interessadas da cidade? A cidade incentiva talentos que contribuam para a economia?
  • Setores de energia: Quão avançado é o setor de serviços urbanos? A cidade está aplicando tecnologias, como sistemas de semáforo inteligente controlados por Inteligência Artificial (AI), soluções de armazenamento de energia em casa, painéis solares e infraestrutura para carregamento de EV?

A partir da avaliação acima, uma cidade é inteligente com base no fato de implementarem tecnologias avançadas para otimizar seus processos, custos e ofertas de serviços. Eu não preciso saber onde você mora aqui no Brasil, e nem ser vidente pra saber que sua cidade hoje (em 2018) provavelmente não é uma cidade inteligente.

2. Por que nossas cidades não são inteligentes?

Para responder essa pergunta, irei fazer algumas outras perguntas (e respostas) para você poder entender melhor os motivos.

a. A inovação é sempre visível?
A inovação pode assumir muitas formas diferentes. Muitas vezes ouvimos falar das tecnologias empolgantes e chamativas que estão em destaque nas manchetes do meios de comunicação, mas menos empolgantes, mas igualmente impactantes, são inovações como uma nova maneira de organizar uma equipe ou um novo sistema de gerenciamento.

b. As nossas expectativas sobre o que uma cidade inteligente é alta demais?
Todos os dias, ouvimos falar de uma nova tecnologia que melhorará drasticamente nossas vidas – da realidade virtual à tecnologia de reconhecimento facial e serviços robóticos. Essas tecnologias podem estar se tornando mais comuns no setor privado, mas temos expectativas reais de quão rapidamente essas tecnologias podem ser integradas em nossos serviços públicos e infraestrutura?

c. Temos observado alguma melhoria em nossos serviços de coleta de resíduos?
Por exemplo, canais de comunicação mais inovadores, como aplicativos e chatbots? Podemos considerar estes avanços em tecnologia no setor público, com a mesma velocidade com que novas tecnologias vem sendo aplicadas no setor privado?

d. As medições de uma cidade inteligente consideram a experiência do cidadão?
Os cidadãos têm diferentes prioridades para as autoridades municipais e a agenda da cidade inteligente – eles se preocupam em viver suas vidas – sobre suas famílias, suas carreiras e seu bem-estar. Talvez tudo o que eles esperam é que os serviços pelos quais pagam (através de impostos) atendam às suas necessidades e trabalhem perfeitamente ao lado de suas vidas ocupadas. Talvez esses serviços pudessem:

  • Incorporar a IA (Inteligencia Artificial) nos smartphones para fornecer orientação se eles se perderem ou sofrerem atrasos durante seus deslocamentos?
  • Usar VR (realidade virtual) para adicionar um valor experiencial ao sistema de transporte da cidade?
  • Identificar um médico adequado para fornecer uma consulta, sem longos períodos de espera ou vários encaminhamentos?
  • Serviços interconectados, para que eles não precisem fornecer repetidamente as mesmas informações em todos os lugares (ou seja, um sistema “único” em vez de um sistema desconectado)?
  • Fornecer interfaces e dispositivos digitais acessíveis e intuitivos para pessoas de todas as idades para gerenciar suas utilidades e obter insights sobre seu uso de energia?

3. Como as nossas cidades podem ser inteligentes para os cidadãos?

As cidades existem para atender às necessidades das pessoas – sejam elas de trabalho, educação, sistema de saúde ou cultura. As necessidades das pessoas devem estar no centro dos nossos serviços públicos e privados. Apesar de uma tendência crescente para o design centrado no usuário, as empresas ainda tendem a ditar a agenda da cidade. Como podemos reorientar sua abordagem para garantir que as necessidades dos cidadãos sustentem o design e a execução dos serviços da cidade?

E se as autoridades e empresas da cidade utilizassem uma abordagem de baixo para cima para a inovação – garantindo que as ideias, os processos e as tecnologias se baseassem na contribuição dos cidadãos? Isso pode não apenas resultar em serviços mais inteligentes, mas também produzir uma melhor experiência do usuário para os cidadãos, que se sentiriam mais capacitados em como as cidades são definidas – em vez dos grandes provedores de serviços que atualmente dominam o mercado. Um passo para isso é uma estratégia de implementação de longo prazo que instrui as pessoas que executam esses serviços e estão em contato direto com o usuário. Ao incorporar sua opinião e experiência, poderíamos oferecer uma abordagem mais focada no ser humano, refinada e fundamentada em pesquisa?

4. A solução pode ser encontrada no design de serviços?

O que as “cidades inteligentes” podem fazer para implementar e melhorar sua experiência de serviço? E se os seguintes princípios sustentassem nossas cidades?

  • Foco no Usuário: O cidadão deve estar no centro de todo serviço.
  • Co-Criatividade: Cidadãos, setores público e privado devem estar envolvidos no processo.
  • Sequenciamento: Os serviços devem ser visualizados por seqüências ou momentos-chave do cliente, é importante entender o que e quando as coisas acontecem. Antes, durante e depois do serviço.
  • Evidenciamento: Todos os envolvidos no fornecimento do serviço precisam estar cientes da experiência do serviço.
  • Holística: O design de um serviço deve levar em conta toda a experiência do serviço. O contexto é importante.

No Reino Unido, o Governo (Gov.uk) já implementou com sucesso uma estrutura de design de serviço, que segue uma abordagem de design focado no ser humano. Isso é demonstrado pelos Serviços Digitais do Governo (GDS) que estão liderando a transformação dos serviços do governo do Reino Unido de físicos para digitais. A GDS tem seu próprio conjunto de princípios de design, mas, em geral, sua estratégia de processo e serviço reflete os 5 princípios acima mencionados por Marc Stickdorn. É geralmente aceito na indústria do design que você deve “sempre começar com o usuário”.

Uma solução é que as cidades inteligentes aspirantes considerem seu próprio conjunto de princípios. Isso permitiria aos provedores de serviços do setor público introduzir uma abordagem focado no usuário, mas também ofereceria um conjunto de princípios a serem seguidos por empresas privadas. Uma questão a considerar é como poderíamos aplicar essa abordagem a todos os serviços da cidade?

Embora o governo seja um grande exemplo para o setor público e privado, a maioria dos serviços municipais não é apenas pública e, portanto, não há padrões para garantir a qualidade nos serviços urbanos. Isso parece especialmente importante para grandes cidades inteligentes como Londres ou Nova York, que lutam para competir com cidades inteligentes menores, como Copenhague ou Amsterdã, já que o tamanho populacional maior interfere nos serviços e nas experiências que uma cidade inteligente oferece.

Serviços como energia, educação e transporte são parcialmente substituídos por organizações privadas e muitas vezes não colocam o usuário em primeiro lugar ou pensam em uma experiência de serviço holística antes de criar seus serviços. Organizações privadas e públicas têm uma agenda diferente; a questão é como eles podem se tornar mais alinhados?

5. Conclusões

Como podemos ver no artigo, se tornar uma cidade realmente inteligente não é algo fácil, e não acontece da noite pro dia. É um trabalho que precisa de tempo e muito esforço para se materializar. Eu não conheço todas as cidades do Brasil, mas as que conheço não consigo ver nenhuma como um cidade inteligente.

Meu objetivo neste post, foi mostrar pra você que pra ser uma cidade inteligente é muito mais complexo do que apenas liberar acesso “Wi-fi” para a população, é um caminho duro e tortuoso até poder chegar ao nível de se intitular uma cidade de “inteligente”.

Fonte: Organicity

by Fernando Quadro at November 19, 2018 10:30 AM