Entrades classificades amb: QGIS

Primers passos en el rutatge al QGIS

En aquest post mostraré els passos que he hagut de seguir per tal de crear el primer dels mòduls que utilitza funcions de rutatge en el QGIS. En aquest cas, volem traslladar el mòdul que calcula els 3 camins a les escoles bressol i llars d’infants més pròximes a cada portal de la ciutat de Mataró. En primer lloc presento les capes amb les quals es treballa. Llavors segueixo amb la creació del mòdul i la seva utilització.

Capes de treball

Actualment amb el GeoMedia treballem amb bases de dades de Microsoft Access majoritàriament. Aquestes incorporen tot tipus de dades, ja sigui taules amb informació sobre el padró o el cadastre, que no estan georeferenciades, o capes de punts, línies o polígons com poden ser els mapes de carrers, illes, cruïlles i serveis públics de la ciutat. Les dades en aquest format ens permeten una gran versatilitat d’ús i facilitat tan en l’ús com en la creació, modificació i eliminació. També són fàcilment exportables a qualsevol altre tipus de format per seguir treballant. Ocasionalment també treballem amb arxius SHAPE.

El QGIS permet gestionar formats raster i vectorials a través de les biblioteques GDAL i OGR, així com altres bases de dades. Una biblioteca GDAL i OGR és un conjunt de programes que estan formats per comandes, cada un amb moltes possibilitats d’ús.

Les capes més comunes amb les quals hem treballat són el Vector Layer, on utilitzem arxius SHAPE (.shp), i Delimited Text Layer on utilitzem arxius CSV (.csv).

Ambdos tipus de dades poden ser modificats fàcilment: tan crear, inserir, modificar o eliminar objectes i/o camps, la qual cosa els fa idonis treballar amb aquests tipus d’arxius ja que si volem fer proves per poder desenvolupar les consultes o els mòduls, ens són de gran utilitat.

Procés de creació

Per crear la interfície gràfica s’utilitza un creador de models que porta incorporats una sèrie de funcionalitats. Haurem d’anar a la caixa d’eines de processat i allà “crear model nou”.
fuc
I seguidament se’ns obra la següent finestra:
nou
Les dues imatges següents corresponen a la columna de l’esquerra de l’anterior imatge hi tenim tots els tipus de paràmetres amb els quals podem treballar, i si canviem a la pestanya de algoritmes, trobem totes les funcions amb les quals podrem treballar sobre les dades. Cal veure el funcionament d’aquestes per tal de poder-les utilitzar correctament.

fuc

dades

 

 

 

 

 

Seguidament, vam afegir el tipus de dades i buscar les funcionalitats adequades per construir la interfície gràfica.

dades2
Una vegada introduïdes les capes, va ser necessari buscar una funcionalitat que convertís el tipus de geometria dels objectes de les capes de punts ja que van sorgir problemes per què obteníem una capa buida. En el nostre cas vam utilitzar el mòdul “Convert Geometry type”.
convert
Seguidament vam començar la recerca d’entre les funcionalitats alguna que calculi una ruta entre dos punts. No existeix una funcionalitat que faci tal funció, així que vam seguir la cerca. Vam seguir buscant entre els plugins que permet instal·lar el QGIS. Vam trobar-ne un que si que fa aquesta funció però no ens era d’utilitat ja que no hi ha cap manera d’automatitzar el procés de càlcul de les distàncies. Això doncs, vam recórrer a l’últim recurs: crear un script en Python que realitzi la funció.

Vam trobar un script que calculava la ruta entre dos punts sobre un graf de carrers. Aquest script utilitza una funció interna de la API de QGIS anomenada “dijkstra” que et retorna un camí. El següent script és el que vam trobar a Internet:

##ruta=name
##ruta=name
##points=vector
##network=vector
##output=output vector

#Algorithm body
#==================================
from PyQt4.QtCore import *
from PyQt4.QtGui import *

from qgis.core import *
from qgis.gui import *
from qgis.networkanalysis import *
from processing.tools.vector import VectorWriter

point_layer = processing.getObject(points)
network_layer = processing.getObject(network)
writer = VectorWriter(output, None, [QgsField("order", QVariant.Int)],
network_layer.dataProvider().geometryType(), network_layer.crs())

# prepare graph
vl = network_layer
director = QgsLineVectorLayerDirector(vl,-1,'','','',3)
properter = QgsDistanceArcProperter()
director.addProperter( properter )
crs = vl.crs()
builder = QgsGraphBuilder( crs )

# prepare points
features = processing.features(point_layer)
point_count = point_layer.featureCount()
points = []
for f in features:
  points.append(f.geometry().asPoint())
tiedPoints = director.makeGraph( builder, points )
graph = builder.graph()
route_vertices = []

for i in range(0,point_count-1):
    progress.setPercentage(int(100 * i/ point_count))
    
    from_point = tiedPoints[i]
    to_point = tiedPoints[i+1]
    from_id = graph.findVertex(from_point)
    to_id = graph.findVertex(to_point)

    (tree,cost) = QgsGraphAnalyzer.dijkstra(graph,from_id,0)
    if tree[to_id] == -1:
        continue # ignore this point pair
    else:
        #collect all the vertices between the points
        route_points = []
        curPos = to_id 
        while (curPos != from_id):
            route_points.append(graph.vertex(
graph.arc(tree[curPos]).inVertex()).point())
           curPos = graph.arc( tree[ curPos ] ).outVertex()
        route_points.append(from_point)
    # add a feature
    fet = QgsFeature()
    fet.setGeometry(QgsGeometry.fromPolyline(route_points))
    fet.setAttributes([i])
    writer.addFeature(fet)
del writer

Un cop testejat i debuguejat, vam començar amb la modificació de l’script per tal d’obtenir el resultat desitjat. Aquest va ser un procés complex ja que s’havia de canviar el programa per dins. Després de forces entrebancs en el procés vam aconseguir un resultat força aproximat al que volíem. Van caldre forces hores per acabar de depurar el codi ja que teníem petits errors que costaven de detectar.

##dintreilla=vector
##EscolesBressol=vector
##network=vector
##output=output vector
#Algorithm body
#==================================
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import time
from qgis.core import *
from qgis.gui import *
from qgis.networkanalysis import *
from processing.tools.vector import VectorWriter

start_time = time.time()
network_layer = processing.getObject(network)

inputPoint = processing.getObject(dintreilla)
features = processing.features(inputPoint)

inputPoint2 = processing.getObject(EscolesBressol)
features2 = processing.features(inputPoint2)

di= 0
eb= 0
id = -1
fields = []
fields.append (QgsField("ID", QVariant.Int))
fields.append (QgsField("Length", QVariant.Int))
fields.append(QgsField("From_Node",QVariant.String))
fields.append(QgsField("To_Node",QVariant.String))

writer = VectorWriter(output, None, 
fields, network_layer.dataProvider().geometryType(), network_layer.crs())

#Per buscar els 3 millors de cada punt

for fea1 in features:
    di=di+1
    #xx = fea1.geometry().asPoint().x()
    #yy = fea1.geometry().asPoint().y()
    #pStart = QgsPoint(xx, yy)
    from_node = fea1.attributes()
    inici = from_node[0]
    print inici
    fea2=None
    features2 = processing.features(inputPoint2)
    eb = -1
    vec = []
    for fea2 in features2:
        eb=eb+1
        id  = id + 1
        nom = fea2.attributes()
        desti = nom[2]
       #---------------------------------------------------------------
        vl = network_layer
        director = QgsLineVectorLayerDirector(vl,-1,'Cost','Cost_inver','',3)
        properter = QgsDistanceArcProperter()
        director.addProperter(properter)
        crs = vl.crs()
        builder = QgsGraphBuilder(crs ,True,0.001)

        # prepare points
        points = []
        points.append(fea1.geometry().asPoint())
        points.append(fea2.geometry().asPoint())

        tiedPoints = director.makeGraph( builder, points )
        graph = builder.graph()

        route_vertices = []
        for i in range(0,2-1):
            from_point = tiedPoints[i]
            to_point = tiedPoints[i+1]

            from_id = graph.findVertex(from_point)
            to_id = graph.findVertex(to_point)

            (tree,cost) = QgsGraphAnalyzer.dijkstra(graph,from_id,0)
            if tree[to_id] == -1:
                continue # ignore this point pair
            else:
                # collect all the vertices between the points
                route_points = []
                curPos = to_id 
                while (curPos != from_id):
                    route_points.append(graph.vertex(
graph.arc(tree[curPos]).inVertex()).point())
                    curPos = graph.arc(tree[curPos]).outVertex()

                route_points.append(from_point)

            # add a feature
            geom=QgsGeometry.fromPolyline(route_points)
            fet = QgsFeature()
            fet.setGeometry(QgsGeometry.fromPolyline(route_points))
            fet.setAttributes([id, geom.length(), inici, desti])
            vec.append(fet)
           
    if (len(vec) > 0):
        vec.sort(key=lambda vec: vec[1])
        for i in range (0,3):
            writer.addFeature(vec[i])
del writer
print("--- %s seconds ---" % (time.time() - start_time))

Finalment vam aconseguir un resultat que s’ajustava a les nostres necessitats, i així completar el procés de creació d’un mòdul amb el QGIS. Vam posar l’script en un mòdul per a python, vam posar-li totes les connexions necessàries.
python
I aquest en va ser el resultat final de tot el procés:
final

Procés d’utilització

Aquí es descriu el procés d’utilització del mòdul per trobar els 3 Camins més pròxims a una Escola Bressol i una d’infants. Aquest comença amb la preparació de les dades a la llegenda o panell de capes del QGIS. En el cas que ens ocupa necessitarem 4 capes SHAPE, 3 de punts i una de segments. Les 3 capes de punts són les Escoles Bressol, les Llars d’Infants  i els dintreilles, que són tots els portals de la ciutat.  I la capa de segments són el conjunts de carrers de la ciutat, és a dir, per on hem de trobar el camí.

Primer de tot, hem de tenir les capes en el tipus desitjat: SHAPE. En el cas que no estiguin ja en aquest format, cal transformar-les per tal de poder-hi treballar. Un cop les tinguem, les guardem per tal de poder-les agafar i emprar.

Tal com s’indica a la fotografia, s’afegeix cada capa via Capa -> Añadir capa -> Añadir capa vectorial:
afe3

afe

Seleccionem explorar i amb l’ajuda de la finestra, busquem els arxius SHAPE que volem posar.

afe2

Repetim l’acció 3 vegades més fins a aconseguir les 4 capes desitjades, tal i com es veu a la foto.

Un cop fet, anem al panell de la dreta de la pantalla on hi ha la “caja de herramientas de procesado” i busquem a l’apartat de Modelos -> CCU, un model anomenat “3EB més pròximes”.
afe4

Una vegada trobat, cal executar-lo. S’obrirà una pestanya amb el següent diàleg:

afe5

Posem a cada pestanya la capa que ens demani: a la primera hi posem la xarxa de carrers sobre la qual volem treballar, a la segona hi posem els Dintreilles o portals de la ciutat(assegurar-se de que sigui la versió “dintreilla_trajectes”) i finalment les escoles bressol o les llars d’infants. Haurem de repetir el procés per cada una de les capes: una per les EB i una altre per les LI.

Un cop tot estigui a punt, només cal executar el procés i esperar a obtenir el resultat. El temps d’espera pot variar segons l’ordinador on s’estigui executant aquest.

Quan finalitzi el procés cal guardar el resultat en un fitxer SHAPE, ja que està en un fitxer temporal i per tant, es perdria en el moment en què tanquem el programa.

Prova del mòdul

En aquest apartat es mostra un exemple de mostra del mòdul. No utilitzaré la capa del ‘dintreilla’ ja que es massa gran i per veure el funcionament, amb una simple capa en tenim prou.

En aquest cas utilitzaré una capa amb un punt (de color vermell) que serà el punt d’origen i una altre capa (de color verd) amb els possibles destins més propers. D’aquesta manera es pot veure ben clar el funcionament.
ex1

Posem en marxa el mòdul i el resultat que obtenim és el següent:

ex2

A la imatge es pot veure el graf de carrers de la ciutat de Mataró. S’hi pot veure 3 camins ressaltats de color verd clar. Tots tres tenen com a origen el punt vermell.

Primeres consultes amb el QGIS

En aquest post, veurem com es fan consultes bàsiques com ara la població que viu a cada illa  o parcel·la de la ciutat de Mataró. El QGIS permet fer uns mapes temàtics molt clars. Per tal de realitzar aquesta consultes, hem de seguir els següents passos:

Primera consulta: habitants per illa

El primer pas és incloure en el nostre projecte la capa de illes i el padró de la ciutat. Un cop fet això, farem un join d’aquestes dues taules utilitzant el camp que tenen en comú: “D_S_I”. Fem la unió dins les propietats de la taula padró.

1. Afegim la connexió.

2. Escollim la taula ‘illes’ i el camp en comú.

Ja tenim la unió feta.

Un cop feta la unió, calculem el número d’habitants que té cada illa de la ciutat. Per tal de realitzar aquesta consulta hem d’utilitzar la funció “GroupStats”. En el cas que no la tingueu, heu d’instal·lar el plug-in.

Un cop aquí, hem d’arrossegar els paràmetres amb els quals volem treballar. En el nostre cas seran els següents: D_S_I i ID1, i també amb l’operador ‘count’, i els disposarem en les diferents files i columnes:

Un cop fet, executem la consulta i obtindrem la següent taula:

Seguidament, exportem la taula en un arxiu .csv i la incorporem en el projecte QGIS en el que estem treballant.

Seguim fent un join per tal de connectar les taules ‘Illes’ i ‘Count_Taules’ i així poder fer el mapa temàtic.

Posteriorment, canviem l’estil de les propietats de la capa “Illes” per tal que mostri les dades de població de cada illa de la ciutat.

Obrim la pestanya d’estils de la capa i el que hem de fer és canviar la pestanya superior de “Símbol únic” a “Graduat”, triar la columna amb les dades de població i clicar el botó de “classificar”. La funció d’aquest darrer botó és fer un classificació de les dades que es mostren i identifica cada interval amb un color diferent.

El QGIS ofereix grans possibilitats a l’hora de fer mapes temàtics com per exemple podem afegir o treure intervals i canviar el color identificatiu interval segons convingui.

Apliquem els canvis i ja tenim el mapa llest per ser consultat.

Segona cosulta: habitants per parcel·la

Per a realitzar aquesta consulta hem de seguir uns passos molt similars als que hem seguit abans. El primer pas és fer un join de les taules “Padro” i “parcel” que comparteixen l’atribut “REFCAD”. Realitzem aquesta acció des de les propietats de la taula Padro.

Afegim una nova conexió premen el botó “+” i seleccionem la capa de les parcel·les. Seguidament esollim els camps en comú i creem la unió.

Hem d’obtenir aquest resultat:

Un cop feta la unió, calculem el número d’habitants que té cada parcel·la de la ciutat. Per tal de realitzar aquesta consulta hem d’utilitzar la funció “GroupStats”. En el cas que no la tingueu, heu d’instal·lar el plug-in.

Li donen les instruccions necessaries per tal d’obtenir el resultat correcte:

I el resultat que obtindrem serà el següent:

Seguidament, exportem la taula en un arxiu .csv i la incorporem en el projecte QGIS en el que estem treballant.

Un cop fet això, només queda fer la unió d’aquesta taula amb la capa de les parcel·les i donar-li un estil graduat per tal d’obtenir el resultat desitjat en el mapa.

 

Aquí fem la unió de les taules.

Aquí canviem l’estil de les diferents categories que hi han i el resultat és el següent:

Iniciació al software QGIS (Quantum GIS)

Fins ara, en el CCU s’ha treballat en un entorn Windows-Geomedia fent la programació en Visual Basic degut a la gran facilitat d’ús d’aquest entorn i a la seva generalització en tots els àmbits tant de l’Empresa Privada com de l’Administració. Però, darrerament, el Programari Lliure s’ha anat obrint camí allà on abans només hi havia programari de propietari. Malgrat tot, encara resten molts inconvenients pels usuaris del Programari Lliure que s’han d’anar superant.

En aquest sentit, s’ha començat un projecte que té com a finalitat el pas total de tota la operativa desenvolupada en l’entorn Geomedia a Programari Lliure, i concretament els mòduls funcionals que s’han anat creat com a plug-ins del Geomedia.

Així doncs, en aquesta primera entrada es parla del QGIS com a alternativa al GIS de desktop Geomedia Professional i s’explica de la forma més entenedora possible els primers passos per iniciar-se en aquest nou entorn.

Aquest nou entorn a treballar és el Programari Lliure QGIS. És un Sistema d’informació Geogràfica (SIG) de codi lliure per plataformes GNU/Linux, Unix, Mac OS i Microsoft Windows. Permet gestionar formats raster i vectorials a través de les biblioteques GDAL i OGR, així com altres bases de dades.

QGIS permet construir d’una forma més senzilla i gràfica models que realitzen les mateixes funcions que, actualment, desenvolupen els mòduls utilitzats al GeoMedia. I el més important, l’elaboració d’aquests models al QGIS es realitzen en molt menys temps que si es volgués fer amb el GeoMedia, tot i que requereixen un elevat temps previ d’investigació. A més, QGIS ofereix una àmplia gamma de funcionalitats que el GeoMedia no ofereix.

Per tant, la finalitat d’inicar-se en aquest nou programa és acabar substituint l’actual programa que es fa servir, el GeoMedia Professional.

Primers passos en el QGIS.

El primer que s’ha de fer en executar per primera vegada el programa, és carregar en la llegenda totes aquelles capes que siguin necessàries per poder treballar i realitzar les corresponents consultes.

En aquest cas, es carreguen dos tipus de capes:

  • Vector Layer: Es tracten d’arxius tipus “shape”. Aquest arxius són aquelles capes que tenen alguna forma geomètrica (punt, línia, polígon). Exemples d’aquestes capes són les illes, les parcel·les, els  números de policia, les entitats base, etc. Per efectuar la càrrega, primer de tot s’han d’exportar aquests “Arxius Shape” des del GeoMedia.
  • Delimited Text Layer: Es tracten d’arxius tipus “CSV”. Per tant, són arxius en format taula, on dins d’aquestes, es troba una sèrie d’informació que serà necessària per efectuar futures consultes. Igual que amb els Arxius Shape, també s’han d’exportar des del GeoMedia.

1. Afegir les capes “Vector Layer” al QGIS

  • El primer pas a seguir, es exportar les capes des del GeoMedia. Un cop dins del GeoMedia Professional, es realitza l’exportació de les capes que interessi.

Fig. 1. Exportació dels arxius shape.

  • S’indiquen aquelles capes que es vulguin exportar, per exemple, les illes, i es clica en “Aplicar”.

Fig. 2. Exportació de les Illes.

  • Un cop s’han exportat les capes des del GeoMedia, s’executa el QGIS i s’importen aquestes capes. Es clica en “Add Vector Layer”.

Fig. 3. Importar capes en format shape.

  • Es busca la ubicació de l’arxiu i es polsa en “Open”.

Fig. 4. Importar capes en format shape.

  • A continuació, apareix la capa “Illes” en la llegenda del QGIS i per tant, es mostra per pantalla tot el mapa de Mataró.

Fig. 5. Mapa de Mataró (Illes).

  • És molt important indicar en cada capa que s’afegeix, el seu sistema de coordenades de referència (ha de ser el mateix que el del GeoMedia: EPSG:23031 – ED50 / UTM zone 31N). Si s’afegeix  una capa, i per defecte no té  aquest sistema de coordenades, la capa no es mostrarà en pantalla. Per fer això, es fa doble clic a sobre de la capa i es va a la pestanya “General”.

Fig. 6. Canviar Sistema de Coordenades.

  • Repetir aquests passos per totes aquelles capes que es vulguin afegir.

2. Afegir les capes “Delimited Text Layer” al QGIS

  • Igual que s’ha fet amb les capes “vector layer”, primer de tot s’han de realitzar les exportacions d’aquelles taules que es vulguin fer servir al QGIS des del GeoMedia. Però, en aquest cas, no existeix una opció al GeoMedia per poder fer-ho directament. Les taules que es desitgin exportar per afegir-les posteriorment al QGIS, han d’estar en format CSV, és a dir, delimitades per comes. Això es pot realitzar des del mateix Excel. Per tant, una opció per dur a terme l’exportació, és anar a buscar la taula que interessi en la base de dades (BBDD) que utilitza el GeoMedia per la taula en concret. En aquest cas, es farà l’exportació de la Taula Resum, que es troba en la BBDD “Padro28Feb14”.

Fig. 7. Exportar les taules a l'Excel.

  • Un cop realitzada l’exportació de la taula des de l’Access, s’obre l’arxiu generat en Excel i es guarda en “CSV (delimitado por comas)”.

Fig. 8. Guardar en format csv.

  • Ara, un cop dins del QGIS, es procedeix a carregar les taules exportades. Es clica en “Add Delimited Text Layer”.

Fig. 9. Importar capes en format CSV.

  • Es busca la ubicació de l’arxiu, es seleccionen les opcions “First record has field names” i “No geometry (attribute only table)” i es clica en “OK”.

Fig. 10. Importar capes en format CSV.

  • A continuació, apareix la capa “Resum” en la llegenda del QGIS i es pot comprovar que tota la informació que conté la taula és correcte. Per fer això, es clica amb el botó dret del ratolí a sobre de la taula i es selecciona “Open Attribute Table”.

Fig. 11. Comprovar informació correcte.

  • Repetir aquests passos per totes aquelles capes que es vulguin afegir.

Editar elements de la llegenda

Un cop ja s’han carregat en la llegenda del QGIS els elements corresponents (entitats, illes, taules…), aquests elements poden ser editats i visualitzar les seves propietats. A continuació, s’explica com fer-ho per l’entitat “Escoles Bressol”, que prèviament ha hagut de ser carregada a la llegenda de la mateixa manera que s’ha fet amb les Illes, seguint el mateix procediment.

  • Si es fa activa la capa de l’entitat “Escoles Bressol” perquè es visualitzin per pantalla, es pot consultar informació de cada una de les escoles que es troben a Mataró. Per fer això, s’ha de clicar a “Identify Features” que es troba en la barra d’eines superior.

Fig. 12. Consultar informació.

I a continuació, clicar a sobre del mapa a l’Escola Bressol que es vulgui consultar i apareixerà una sèrie d’informació.

Fig. 13. Informació de l'Escola Bressol.

  • Una altra manera de visualitzar la informació de les Escoles Bressol sense haver d’anar clicant una per una, és clicar amb el botó dret a sobre de “EscolaBressol” que es troba en la llegenda i seleccionar “Open Attribute Table”.

Fig. 14. Open Attribute Table.

S’observa com es visualitza la taula amb tota la informació de cada una de les Escoles Bressol.

Fig. 15. Informació de les Escoles Bressol.

  • Si el que es vol es visualitzar les propietats de les entitats, el que s’ha de fer és pitjar amb el botó dret a sobre de “EscolaBressol” i clicar a “Properties”.

Fig. 16. Propietats de les Escoles Bressol.

En la següent entrada d’aquest bloc, s’explicarà com construir un model des del QGIS que realitzi les mateixes funcions que, actualment, realitza en el GeoMedia.