OSGeo Planet

gvSIG Team: Curso Gratuito: SIG aplicados a Arqueología

OSGeo Planet - Wed, 2018-12-19 11:56

En los últimos años, los Sistemas de Información Geográfica (SIG) han evolucionado de forma radical la forma en que los datos espaciales se recopilan, analizan e interpretan. Por sus características los SIG se han convertido en aplicaciones de gran utilidad para los arqueólogos. La aparición de gvSIG, con una suite completa de soluciones SIG en software libre, ha hecho que en la actualidad sean cada vez más los profesionales del sector que adoptan gvSIG como herramienta de trabajo.

Sin embargo aún hay un amplio desconocimiento del potencial de los SIG en arqueología, y poco acceso a material educativo y gratuito que permita formarse en su uso. Por estos motivos, desde la Asociación gvSIG, lanzamos un curso que pretendemos que ayude a dar a conocer estas tecnologías. Un curso gratuito, con software libre y gratuito (gvSIG Desktop).

En este primer post queremos presentaros las características principales del curso, junto al primer vídeo-tutorial. A partir de enero de 2019 iremos publicando semanalmente todos los módulos hasta completar el temario. Para aprovechar al máximo el curso se recomienda que los participantes tengan un conocimiento previo de cómo se llevan a cabo los proyectos arqueológicos.

Inscripción y funcionamiento del curso

No es necesario inscribirse en ningún sitio. El curso es online y se podrá realizar desde cualquier parte del mundo. El curso estará disponible en inglés y castellano.

Cada semana publicaremos un post en este blog que tendrá un vídeo-tutorial con ejercicios y acceso a los datos del curso. Por tanto, sólo necesitáis ir siguiendo los vídeo-tutoriales para completar el curso.

Para dudas en el manejo del software, realización de los ejercicios y problemas que puedan surgir en la realización del curso, podéis utilizar la lista de usuarios de gvSIG:

http://www.gvsig.com/es/comunidad/listas-de-correo

Temario

El temario se compone de 7 módulos. Cada módulo presentará un vídeo-tutorial con ejercicios prácticos. Los datos para poder seguir el curso los podéis descargar comprimidos en un fichero .zip de este enlace.

  1. Preparación de un proyecto arqueológico: vistas, capas y tablas
  2. Crear información geográfica: Información alfanumérica y digitalización
  3. Análisis de resultados de prospecciones: Geoprocesos vectoriales
  4. Gestionando mapas antiguos: Georreferenciación de imágenes
  5. Análisis territorial de yacimientos: Geoprocesos ráster y modelos digitales de terreno (MDT)
  6. Análisis hidrológico para localizar materiales o yacimientos arqueológicos
  7. Salida gráfica de un proyecto arqueológico: Mapas
¿Y si quiere obtener un certificado?

Como en otros cursos anteriores que hemos publicado, muchos de vosotros nos preguntáis por la posibilidad de obtener un certificado. Para cubrir esta posibilidad, al final del curso publicaremos un ejercicio práctico a resolver que permitirá demostrar que habéis adquirido los conocimientos impartidos durante el curso. La realización de este ejercicio es totalmente opcional. Sólo para aquellos que quieran tener la certificación.

Para costear el tiempo de evaluación de los ejercicios y la emisión del certificado, además de entregar el ejercicio correctamente resuelto habrá que abonar 25 €. La forma de pago se indicará junto al ejercicio final.

Tema 1: Preparación de un proyecto arqueológico: vistas, capas y tablas

¿Preparados? Pues vamos a comenzar con el primer tema, donde además de aprender de dónde descargar gvSIG Desktop – el software que utilizaremos para el curso – veremos como preparar un proyecto arqueológico trabajando con los principales componentes de un SIG: Vistas, capas y tablas.

Categories: OSGeo Planet

Fernando Quadro: Planet Labs adquire Boundless

OSGeo Planet - Wed, 2018-12-19 11:55

A Planet Labs anunciou ontem a aquisição da Boundless Spatial, Inc., empresa de soluções de software geoespacial com sede em St. Louis, que é a responsável pelo desenvolvimento do GeoServer. A aquisição expande os negócios comerciais da Planet com o governo dos EUA e clientes da agricultura comercial. A Boundless é líder em software de gerenciamento de dados geoespaciais e está alinhada com o objetivo de fornecer novos serviços de assinatura de dados geoespaciais e acelerar a adoção em clientes corporativos.

Com a aquisição da Boundless, a Planet pretende alavancar a tecnologia e o conhecimento da Boundless implantados dentro do governo dos EUA para facilitar ainda mais a utilização dos seus produtos. Além disso, este acordo também trará novos clientes do governo dos EUA para Planet.

A Planet manterá o escritório da Boundless em St Louis (MO) e em conjunto com a equipe da Planet que trabalha diretamente com o governo dos EUA formará uma subsidiária chamada Planet Federal.

Sobre os outros escritórios da Boundless nos EUA, e também sobre os funcionários que trabalham remotamente nada foi dito!

Fonte: Planet

Categories: OSGeo Planet

MapTiler: OpenMapTiles 3.9

OSGeo Planet - Tue, 2018-12-18 11:00
Thumb

The new release of OpenMapTiles comes with many smaller changes. Version 3.9 brings rendering of docks and piers, support for multilingual street names and other improvements.

Docks and Piers

The biggest visual change is the newly added support for rendering docks and piers. Piers are now rendered in a similar way like bridges while docks were added to the water layer. This modification will have the biggest impact on complicated harbors structures like Liverpool’s harbor or spectacular structures like the famous Brighton Palace Pier.

OpenMapTiles Liverpool

Multilingual street names

To solve a pain in bilingual countries we added support for multilingual streets. It follows all other map elements like place names, country names or named points of interest. Street name labels are now rendered in all 58 languages and the selection of displayed language is done automatically based on end-user preferences or by an app developer decision.

Many changes for multilingual street names has been made by the Helsinki Regional Transport Authority. They use our maps on their websites, in the application as well as printed on the public transport stops. Another user of OpenMapTiles and contributor to the project is the Qwant map team.

Talking about languages, improvement have been made for Vietnamese and Azerbaijani nonlatin labels and there is brand new support for the Malayalam language.

Other changes in OpenMapTiles 3.9
  • National parks in the Park layer have their names.
  • Indoor POI layer contains layer and level attributes.
  • The type of sport for a pitch POI can be distinguished via subclass attribute.
  • Improved rendering of 3D buildings.
  • Fixed issues with small islands in Scandinavia.

For detailed information, read the full changelog.

View all improvements on our map and start using it via MapTiler Cloud or self-hosted OpenMapTiles.

Categories: OSGeo Planet

GIS for Thought: PostGIS Tutorial Data

OSGeo Planet - Tue, 2018-12-18 09:00

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.

I have created a version of the data used, which can be accesses at (choose the green Clone or download button and Download ZIP):

https://github.com/HeikkiVesanto/postgis_course_data

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

The course has been compiled and can be found at: https://gisforthought.com/boundless-postgis-tutorial/

Categories: OSGeo Planet

Free and Open Source GIS Ramblings: Movement data in GIS #18: creating evaluation data for trajectory predictions

OSGeo Planet - Sat, 2018-12-15 15:31

We’ve seen a lot of explorative movement data analysis in the Movement data in GIS series so far. Beyond exploration, predictive analysis is another major topic in movement data analysis. One of the most obvious movement prediction use cases is trajectory prediction, i.e. trying to predict where a moving object will be in the future. The two main categories of trajectory prediction methods I see are those that try to predict the actual path that a moving object will take versus those that only try to predict the next destination.

Today, I want to focus on prediction methods that predict the path that a moving object is going to take. There are many different approaches from simple linear prediction to very sophisticated application-dependent methods. Regardless of the prediction method though, there is the question of how to evaluate the prediction results when these methods are applied to real-life data.

As long as we work with nice, densely, and regularly updated movement data, extracting evaluation samples is rather straightforward. To predict future movement, we need some information about past movement. Based on that past movement, we can then try to predict future positions. For example, given a trajectory that is twenty minutes long, we can extract a sample that provides five minutes of past movement, as well as the actually observed position five minutes into the future:

But what if the trajectory is irregularly updated? Do we interpolate the positions at the desired five minute timestamps? Do we try to shift the sample until – by chance – we find a section along the trajectory where the updates match our desired pattern? What if location timestamps include seconds or milliseconds and we therefore cannot find exact matches? Should we introduce a tolerance parameter that would allow us to match locations with approximately the same timestamp?

Depending on the duration of observation gaps in our trajectory, it might not be a good idea to simply interpolate locations since these interpolated locations could systematically bias our evaluation. Therefore, the safest approach may be to shift the sample pattern along the trajectory until a close match (within the specified tolerance) is found. This approach is now implemented in MovingPandas’ TrajectorySampler.

def test_sample_irregular_updates(self): df = pd.DataFrame([ {'geometry':Point(0,0), 't':datetime(2018,1,1,12,0,1)}, {'geometry':Point(0,3), 't':datetime(2018,1,1,12,3,2)}, {'geometry':Point(0,6), 't':datetime(2018,1,1,12,6,1)}, {'geometry':Point(0,9), 't':datetime(2018,1,1,12,9,2)}, {'geometry':Point(0,10), 't':datetime(2018,1,1,12,10,2)}, {'geometry':Point(0,14), 't':datetime(2018,1,1,12,14,3)}, {'geometry':Point(0,19), 't':datetime(2018,1,1,12,19,4)}, {'geometry':Point(0,20), 't':datetime(2018,1,1,12,20,0)} ]).set_index('t') geo_df = GeoDataFrame(df, crs={'init': '4326'}) traj = Trajectory(1,geo_df) sampler = TrajectorySampler(traj, timedelta(seconds=5)) past_timedelta = timedelta(minutes=5) future_timedelta = timedelta(minutes=5) sample = sampler.get_sample(past_timedelta, future_timedelta) result = sample.future_pos.wkt expected_result = "POINT (0 19)" self.assertEqual(result, expected_result) result = sample.past_traj.to_linestring().wkt expected_result = "LINESTRING (0 9, 0 10, 0 14)" self.assertEqual(result, expected_result)

The repository also includes a demo that illustrates how to split trajectories using a grid and finally extract samples:

 

Categories: OSGeo Planet

Cameron Shorter: Catching the elusive Episodic Volunteer

OSGeo Planet - Fri, 2018-12-14 22:04

Understanding the science of volunteer contributions is key to the success of Open Source projects. A comprehensive study of episodic volunteering, which drew upon our OSGeoLive experiences, provides insightful advice for anyone wishing to build sustained and successful Open Source Software:

Contributor MotivationFindings: Episodic volunteers with intrinsic motives are more likely to intend to remain, compared to episodic volunteers with extrinsic motives.

Recommendations:
  1. Lower barriers to entry through:
    • Accepting contributions directly through GitHub,
    • Good documentation,
    • Task–finding dashboard,
    • Simple workspace(s).
  2. Offer guided introductory events to help newcomers get started and to introduce the social element.
  3. Provide opportunities for social interactions, such as:
    • Interactive sites, including localised options,
    • Hosting local meetups.
Social NormsFindings: Although Open Source episodic volunteers were unlikely to see their participation as influenced by social norms, personal invitation was a common form of recruitment, especially among non-code contributors.

Recommendations:
  1. Encourage existing volunteers to talk about their Open Source involvement by:
    • Highlighting the benefits of advocating broadly,
    • Providing digestible information for sharing.
Psychological Sense of CommunityFindings: Psychological sense of community is more common among long-term participants;
A policy of inclusion was a commonly mentioned reason for feeling welcomed in the community.

Recommendations:
  1. Use a code of conduct to express the community’s intentions, allowing potential episodic volunteers to determine their similarity to the community.
  2. Give potential episodic volunteers the opportunity to identify alignment with the community through awareness of non-coding activities:
    • Collaborate with organisations with a different focus but shared values,
    • Recognise all forms of contribution.
  3. Re-enforce the psychological sense of community by:
    • Hosting local events,
    • Issuing personal invitations to episodic volunteers.
SatisfactionFindings: Satisfaction was most commonly cited as a reason to remain;
Episodic volunteers derive satisfaction from knowing that their work is used, enjoying the work itself, and feeling appreciated.
Recommendations:
  1. Encourage satisfaction by increasing feelings of appreciation, by recognising all contributors and their areas of expertise.
  2. Being aware of episodic volunteers’ areas of expertise and requesting their assistance, sparingly, can:
    • Make episodic volunteers feel appreciated,
    • Encourage episodic volunteers to return to the community.
Community CommitmentFindings: Episodic volunteers who talk about their involvement are more inclined to continue participating;
Long-term episodic volunteers often have community commitment;
Community commitment is less common among episodic volunteers with extrinsic motives.

Recommendations:
  1. Encourage long-term episodic volunteers to talk about the community to strengthen their commitment to the community and:
    • To utilise Social Norms to recruit friends/family,
    • To recruit from similar organisations through Psychological Sense of Community.
  2. Consider time-based releases for large projects to allow episodic volunteers to plan their return.
  3. Use opt-in platforms to broadcast calls for participation for specific tasks to encourage episodic volunteers to return.
Episodic volunteeringFindings: Episodic volunteering is widespread in Open Source communities, but Open Source communities are often not strategically engaging with episodic volunteers;
Open Source episodic volunteers are often habitual volunteers in other communities.

Recommendations:
  1. Evaluate volunteer assets, volunteer availability, and potential assignments to find opportunities for episodic volunteers.
Categories: OSGeo Planet

Stefano Costa: I libri che ho letto nel 2017

OSGeo Planet - Thu, 2018-12-13 20:45

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.

Categories: OSGeo Planet

Fernando Quadro: Vídeos do FOSS4G Oceania

OSGeo Planet - Thu, 2018-12-13 10:30

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

Categories: OSGeo Planet

gvSIG Team: gvSIG Batoví, más que un concurso una metodología para llevar el SIG a las aulas

OSGeo Planet - Wed, 2018-12-12 18:45

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?

Categories: OSGeo Planet

Stefano Costa: IOSACal on the web: quick calibration of radiocarbon dates

OSGeo Planet - Wed, 2018-12-12 01:27


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.

Categories: OSGeo Planet

Fernando Quadro: Desenvolvimento de plugins do QGIS: Testando seu código

OSGeo Planet - Mon, 2018-12-10 10:30

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

Categories: OSGeo Planet

Fernando Quadro: Desenvolvimento de plugins do QGIS: Plugin AttributeTransfer

OSGeo Planet - Thu, 2018-12-06 10:30

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.

Categories: OSGeo Planet

Fernando Quadro: Desenvolvimento de plugins do QGIS: Criando interface gráfica

OSGeo Planet - Wed, 2018-12-05 10:30

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.

Categories: OSGeo Planet

Fernando Quadro: Desenvolvimento de plugins do QGIS: Vizinho mais próximo

OSGeo Planet - Tue, 2018-12-04 10:30

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.
Categories: OSGeo Planet

GIS for Thought: Copying Rasters in PostGIS

OSGeo Planet - Tue, 2018-12-04 09:00

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.

Categories: OSGeo Planet

QGIS Blog: User question of the Month – Dec 18 & answers from Nov

OSGeo Planet - Mon, 2018-12-03 20:59

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.

Categories: OSGeo Planet

QGIS Blog: Call for presentations: QGIS User Conference and Developer Meeting, 2019

OSGeo Planet - Mon, 2018-12-03 18:07
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 2018. 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!

 

[1] http://qgis.es/ [2] https://xeoinquedos.wordpress.com/ [3] https://www.coruna.gal/

 

Categories: OSGeo Planet

Fernando Quadro: Desenvolvimento de plugins do QGIS: Usando o console

OSGeo Planet - Mon, 2018-12-03 10:30

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.

Categories: OSGeo Planet

Free and Open Source GIS Ramblings: Movement data in GIS #17: spatial analysis of GeoPandas trajectories

OSGeo Planet - Sun, 2018-12-02 16:08

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.

Categories: OSGeo Planet

Cameron Shorter: OSGeoLive in 4 minutes

OSGeo Planet - Fri, 2018-11-30 21:16

Here is our OSGeoLive lightning talk, stripped back to 4 minutes, and presented at the FOSS4G-Oceania conference. OSGeoLive talk starts at 8mins 15secs.
The shortened slide deck and notes are here.
Categories: OSGeo Planet
Syndicate content