Entrades classificades amb: GTC

Implementación de las funcionalidades QGIS3 para realizar el cálculo local en el módulo CTE

En este post se mostrará el proceso de implementación de las nuevas funcionalidades que trae consigo la versión 3 de QGIS, las cuales permiten realizar operaciones complejas ejecutando simplemente un algoritmo. En este caso, se tomará como ejemplo el módulo CTE. Este módulo permite obtener los trayectos o caminos entre una dirección de Mataró y las N entidades más próximas.

Utilización manual de los algoritmos

En primer lugar, se debe habilitar el paquete de “Processing” en el caso de que no esté activado. Para ello se deberá ir a “Complementos” -> “Administrar e instalar complementos…” (Fig. 1).

Fig 1. Habilitar paquete “Processing”.

Tras haberlo habilitado aparecerá una nueva pestaña llamada “Procesos”, en la cual se deberá seleccionar “Caja de herramientas” para que se muestren en pantalla todos los algoritmos disponibles. Dicho elemento aparecerá en una barra lateral dentro de QGIS.

A continuación se debe probar si el algoritmo que se utilizará genera el resultado deseado. En el caso del CTE, el algoritmo que potencialmente puede interesarnos es el denominado “Ruta más corta (punto a capa)”, el cual se encuentra en la sección de análisis de redes (Fig. 2).

Fig 2. Caja de herramientas de procesos.

Dicho algoritmo necesita la capa vectorial que representa la red (en nuestro caso SegmentsXarxaCarrers), un punto de inicio y una capa vectorial con los puntos finales. Para realizar las pruebas se utilizarán (de forma totalmente arbitraria) un punto cualquiera del mapa de Mataró como punto de inicio y los IES como puntos finales. Por tanto, se deberán cargar en QGIS tanto SegmentsXarxaCarrers como los IES (Fig. 3).

Fig 3. Importación de los IES y SegmentsXarxaCarrers.

Abrimos el algoritmo, seleccionamos nuestra red, punto de inicio, puntos finales y el resto de los valores los dejaremos por defecto (Fig. 4). Acto seguido, ejecutamos.

Fig 4. Algoritmo “Ruta más corta (punto a capa)”.

Una vez haya finalizado la ejecución el algoritmo, se añadirá automáticamente el resultado a la leyenda (Fig. 5). Desde el punto arbitrario que se ha escogido en este caso particular el resultado sería el siguiente, en el cual se puede apreciar que produce el resultado deseado (buscar la ruta más corta a cada entidad).

Fig 5. Resultado del algoritmo (rutas más cortas).

Inclusión de los algoritmos en el código

Para poder utilizar los algoritmos proporcionados por QGIS e incluirlos en el módulo, será necesario realizar un “import processing” en el código para poder ejecutar la función “processing.run()”, la cual se encargará de ejecutar el algoritmo deseado. Dentro de esta función se le deberá indicar el ID del algoritmo que se vaya a utilizar y los parámetros que se le pasarán.

Para saber cuál es el ID del algoritmo, simplemente con poner el cursor sobre él nos aparecerá su nombre (Fig. 6).

Fig 6. ID del algoritmo.

Por otra parte, para saber qué tipos admite cada uno de los parámetros (y más información sobre el funcionamiento general del algoritmo) podemos usar la consola de QGIS e introducir el comando “processing.algorithmHelp(“native:shortestpathpointtolayer”)”.

En este módulo se ha querido preservar el cálculo que se realiza en el servidor mediante consultas SQL. Para poder mantener ambas opciones se ha optado simplemente por añadir un checkbox el cual propiciará que el módulo se ejecute en local si se ha marcado y, contrariamente, se ejecutará en el servidor cuando esté desmarcado (Fig. 7).

Fig 7. Checkbox de cálculo local en el módulo CTE.

Por tanto, en el código del módulo se ha escrito la siguiente función, la cual se encarga de ejecutar el algoritmo.

def calculo_Local(self,network_lyr,start_point,end_lyr):
    parameters={'INPUT':network_lyr,
                'STRATEGY':0,
                'DIRECTION_FIELD:'',
                'VALUE_FORWARD:'',
                'VALUE_BACKWARD:'',
                'VALUE_BOTH:'',
                'DEFAULT_DIRECTION':2,
                'SPEED_FIELD':'',
                'DEFAULT_SPEED':1,
                'TOLERANCE':0,
                'START_POINT':start_point,
                'END_POINTS':end_layer,
                'OUTPUT':'memory:'}
    return.processing.run('native:shortestpathpointtolayer',parameters)

A esta función se le pasan los siguientes parámetros:

  • network_lyr: es la capa vectorial que representa la red.
  • start_point: es el punto de inicio elegido por el usuario, es decir, la dirección que haya introducido.
  • end_lyr: es la capa vectorial que representa los puntos finales, es decir, las entidades que haya elegido el usuario.

El resto de parámetros son los que anteriormente se usaban por defecto y, teniendo en cuenta el uso que tiene este algoritmo en el módulo, nos interesa que sean esos valores fijos.

En el módulo CTE lo que se busca es mostrarle al usuario los N caminos más cortos, siendo N un número definido por el propio usuario. El algoritmo genera las rutas más cortas de todas las entidades por lo que, tras haber utilizado el algoritmo, se deberá realizar un filtrado de los caminos que tengan un menor coste según el número de entidades establecido por el usuario.

A partir de este punto, se representará el resultado utilizando el mismo código empleado cuando se realiza el cálculo en el servidor.

Cálculo por distancia/tiempo

El algoritmo utilizado, “Ruta más corta (punto a capa)”, puede funcionar definiendo el coste por distancia o por tiempo. Para realizar el cálculo utilizando la distancia lo que hará es comparar la longitud de los segmentos, mientras que por tiempo tomará el valor que le indiquemos de un campo en concreto o bien asignará una velocidad predeterminada.

En el caso del módulo CTE no representa ningún problema realizar el cálculo por distancia. Sin embargo, si se quisiera hacer el cálculo por tiempo, en la base de datos está definido un coste distinto dependiendo del sentido debido a que no se tarda el mismo tiempo en subir una pendiente que en bajarla. Desafortunadamente, este algoritmo está pensado para asignar una única velocidad para cada segmento sin tener en cuenta el sentido. Por tanto, todo lo que se ha descrito previamente sólo sirve para el caso de la distancia ya que en la actualidad este algoritmo no soporta esta dualidad de velocidades.

Diferencias rendimiento (ventajas/inconvenientes)

Las diferencias de rendimiento entre el cálculo en el servidor y la nueva opción de cálculo local varían en función de lo concurrido que esté el servidor en ese momento y del ordenador del cliente.

A continuación se muestra el tiempo que ha tardado el módulo en calcular cada uno de los destinos en servidor y local en unas pruebas de testeo.

Fig 8. Resultados del testeo. Eje X: puntos finales. Eje Y: tiempo de ejecución.

Tal y como se puede apreciar en el gráfico (Fig. 8), en el caso del cálculo en el servidor el tiempo de proceso aumenta de forma proporcional a la cantidad de entidades de destino que tiene que calcular. Por otra parte, el tiempo que tarda el cálculo local es sumamente sólido, siendo prácticamente una constante. Se tarda el mismo tiempo en calcular 4 destinos (CasalsAvisOficial) que 144 (ParadesBus).

Debido a que el cálculo local presenta una duración más estable, que de media tarda 5 segundos (mientras que el cálculo en el servidor tarda de media 7,9 segundos) y que libera carga en el servidor, esta nueva forma de realizar los cálculos representa una mejora en el módulo CTE y, por norma general, al usuario le interesará ejecutar este módulo marcando el cálculo local.

 

Cálculo en el servidor de los caminos más cortos en el módulo CTE

En este post se explicará cómo se realiza el cálculo en el servidor en el módulo CTE, el cual permite obtener los trayectos o caminos entre una dirección de Mataró y las N entidades más próximas.

Este cálculo se divide en 2 fases: cálculo de los caminos más cortos y la selección de los segmentos finales. Esto es debido a que la función pgr_withPointsKSP  (la cual se utiliza para calcular los caminos más cortos) tiene asociado el problema de que devuelve los caminos del grafo de nodo a nodo, no teniendo en cuenta que en la mayor parte de los casos tanto el punto de inicio como los finales estarán situados en un punto intermedio de un segmento (una arista). Para obtener más información sobre este tema se puede consultar el post “Cobertura mitjançant el graf de trams de carrers (GTC)” de Josep López Xarbau.

Cálculo de los caminos más cortos

En esta primera fase se utiliza la función de PGRouting, pgr_withPointsKSP. Esta función busca los N caminos más cortos utilizando el algoritmo de Yen.

Todo el código que se presentará a continuación pertenece al módulo CTE, el cual está programado en Python y se comunica con la base de datos de Postgres.

En primer lugar lo que nos interesa realizar es unir todos los puntos involucrados (tanto los de destino como el de origen) en una misma tabla para poder prepararlos para la función pgr_withPointsKSP.

De este modo, primero se borra y se crea una nueva tabla para guardar dichos puntos.

drop = 'DROP TABLE IF EXISTS NecessaryPoints_'+Fitxer+';'
try:
    cur.execute(drop)
    conn.commit()
except:
    print ("DROP TABLE ERROR 1")
create = 'CREATE TABLE NecessaryPoints_'+Fitxer+' (\n'
create += "\tpid serial primary key,\n"
create += "\tthe_geom geometry,\n"
create += "\tentitatID int8,\n"
create += "\tedge_id BIGINT,\n"
create += "\tfraction FLOAT,\n"
create += "\tnewPoint geometry);"
try:
    cur.execute(create)
    conn.commit()
except:
    print ("CREATE TABLE NecessaryPoints ERROR")

Acto seguido, se añaden los puntos a la tabla.

insert = 'INSERT INTO NecessaryPoints_'+Fitxer
insert += ' (entitatID,the_geom) (SELECT 0, ST_Centroid("geom") the_geom from "dintreilla"'
insert += ' WHERE "Carrer_Num_Bis" = \''+CNB+'\');\n'

insert += 'INSERT INTO NecessaryPoints_'+Fitxer
insert += ' (entitatID, the_geom) (SELECT "id", ST_Centroid("geom") the_geom FROM"'
insert += self.dlg.comboCapaDesti.currentText() + '" ORDER BY "id");'
try:
    cur.execute(insert)
    conn.commit()
except:
    print ("Insert Points NecessaryPoints ERROR")

Después se añade el id del tramo más próximo a cada punto, los puntos proyectados sobre el grafo y la fracción de segmento en la que se encuentran.

update = 'UPDATE NecessaryPoints_'+Fitxer
update += ' SET "edge_id"=tram_proper."tram_id"'
update += ' FROM (SELECT distinct on(Poi."pid") Poi."pid" AS Punt_id,Sg."id" AS Tram_id,'
update += ' ST_Distance(Sg."the_geom",Poi."the_geom") AS dist '
update += 'FROM "Xarxa_Prova" as Sg,NecessaryPoints_'+Fitxer+' AS Poi '
update += 'ORDER BY Poi."pid",ST_Distance(Sg."the_geom",Poi."the_geom"),Sg."id") tram_proper'
update += ' WHERE NecessaryPoints_'+Fitxer+'."pid"=tram_proper."punt_id";\n'

update += 'UPDATE NecessaryPoints_'+Fitxer
update += ' SET fraction = ST_LineLocatePoint(e.the_geom, NecessaryPoints_'+Fitxer+'.the_geom),'
update += 'newPoint = ST_LineInterpolatePoint(e."the_geom",'
update += ' ST_LineLocatePoint(e."the_geom", NecessaryPoints_'+Fitxer+'."the_geom"))'
update += ' FROM "Xarxa_Prova" AS e WHERE NecessaryPoints_'+Fitxer+'."edge_id" = e."id";\n'
try:
    cur.execute(update)
    conn.commit()
except:
    print ("Update Points NecessaryPoints ERROR")

Ahora ya está todo preparado para poder realizar el cálculo. Se hace una consulta para poder generar una sentencia SQL que haga la búsqueda de todos los caminos más cortos a todos los puntos necesarios y después se añaden a una tabla llamada “Resultat”.

select = 'select * from NecessaryPoints_'+Fitxer+' order by pid'
cur.execute(select)
vec = cur.fetchall() 
create = 'create local temp table "Resultat" as SELECT * FROM (\n'
for x in range (0,len(vec)):
    if x < len(vec) and x >= 2:
        create += 'UNION\n'
    if x != 0:
        if vec[x][4] == 1.0 or vec[x][4] == 0.0:
            create +='select '+ str(x) +' AS routeID,'+ str(vec[x][2])
            create +=' AS entitatID, * FROM pgr_withPointsKSP'
            create +='(\'SELECT id, source, target, cost, reverse_cost '
            create +='FROM "Xarxa_Prova" ORDER BY id\','
            create +='\'SELECT pid, edge_id, fraction FROM NecessaryPoints_'
            create +=Fitxer+'\',-1,' + str(vec[x][2])+',1)\n'
        else:
            create += 'select '+ str(x) +' AS routeID,'+ str(vec[x][2])
            create +=' AS entitatID, * FROM pgr_withPointsKSP'
            create +='(\'SELECT id, source, target, cost, reverse_cost '
            create +='FROM "Xarxa_Prova" ORDER BY id\','
            create +='\'SELECT pid, edge_id, fraction FROM NecessaryPoints_'
            create +=Fitxer+'\',-1,-' + str(vec[x][0]) +',1)\n'
create += ')QW ORDER BY routeID, seq;'

drop = 'DROP TABLE IF EXISTS "Resultat";'
try:
    cur.execute(drop)
    conn.commit()
except:
    print ("DROP TABLE ERROR 2")

try:
    cur.execute(create)
    conn.commit()
except:
    print ("CREATE TABLE Resultat global ERROR")

A continuación se deberá solucionar el problema que se ha comentado en la introducción del post, es decir, se seleccionarán los segmentos que son inicio y final para añadirlos al resultado final.

Selección de los segmentos finales

Lo primero que se debe hacer es borrar y crear la tabla “Segments finals”, en la cual figurarán todos los caminos posibles que son principio y/o final.

drop = "DROP TABLE IF EXISTS \"SegmentsFinals\";"
try:
    cur.execute(drop)
    conn.commit()
except:
    print ("DROP TABLE ERROR 1")

create = "CREATE local temp TABLE \"SegmentsFinals\" (\n"
create += "\trouteid int8,\n"
create += "\tedge int8,\n"
create += "\t\"edgeAnt\" int8,\n"
create += "\tfraction FLOAT,\n"
create += "\t\"ordreTram\" int8,\n"
create += "\t\"cutEdge\" geometry);"
try:
    cur.execute(create)
    conn.commit()
except:
    print ("CREATE TABLE SegmentsFinals ERROR")

Después se realiza una consulta que determinará qué segmentos son inicio y final.

select = 'SELECT routeid, node, edge FROM "Resultat" ORDER BY routeid, path_seq;'
try:
    cur.execute(select)
    vec = cur.fetchall()
    conn.commit()
except:
    print ("SELECT Resultat ERROR")

insert = ''
for x in range (len(vec)):
    if vec[x][1] < 0:
        if vec[x][1] != -1:
            insert +='INSERT INTO "SegmentsFinals" (routeid, edge, "edgeAnt", "ordreTram") '
            insert +='VALUES (' + str(vec[x][0]) + ', ' + str(vec[x-1][2]) + ', '
            insert +=str(vec[x-2][2]) + ', ' + str(2) +');\n'
        else:
            insert +='INSERT INTO "SegmentsFinals" (routeid, edge, "edgeAnt", "ordreTram") '
            insert +=VALUES (' + str(vec[x][0]) + ', ' + str(vec[x][2]) + ', '
            insert +=str(vec[x+1][2]) + ', ' + str(1) + ');\n'
try:
    cur.execute(insert)
    conn.commit()
except:
    print ("INSERT TABLE SegmentsFinals ERROR")

Se realiza un UPDATE para poder añadir la fracción de segmento en la cual se encuentra el punto.

select = 'SELECT routeid, edge, "ordreTram" FROM "SegmentsFinals" ORDER BY routeid, "ordreTram";'
try:
    cur.execute(select)
    vec = cur.fetchall()
    conn.commit()
except:
    print ("SELECT SegmentsFinals ERROR")

update = ''
for x in range(len(vec)):
    ruta = vec[x][0]
    edge = vec[x][1]
    ordre = vec[x][2]
    if ordre == 1:
        update +='UPDATE "SegmentsFinals" s SET fraction = n.fraction FROM NecessaryPoints_'
        update +=Fitxer+' n where n.edge_id = '+str(edge)+' AND s.edge ='+str(edge)
        update +=' AND s."ordreTram" = 1 AND s.routeid = '+str(ruta)+' AND n.entitatid = 0;\n'
    else:
        update +='UPDATE "SegmentsFinals" s SET fraction = n.fraction FROM NecessaryPoints_'
        update +=Fitxer+' n where n.edge_id = '+str(edge)+' AND s.edge ='+str(edge)
        update +=' AND s."ordreTram" = 2 and s.routeid = '+str(ruta)
        update +=' AND n.pid = '+str(ruta+1)+';\n'

try:
    cur.execute(update)
    conn.commit()
except:
    print ("UPDATE TABLE SegmentsFinals ERROR")

A continuación se realiza una consulta para escoger y añadir el trozo de tramo que corresponde a cada inicio y final. Posteriormente se hace un UPDATE del campo de geometría de la tabla “SegmentsFinals” con los tramos ya recortados.

select = 'SELECT * FROM "SegmentsFinals" ORDER BY routeid;'
try:
    cur.execute(select)
    vec = cur.fetchall()
    conn.commit()
except:
    print ("SELECT SegmentsFinals ERROR")
updateSegment = ''
for x in range(len(vec)):
    ordre = vec[x][4]
    fraction = vec[x][3]
    edgeAnt = vec[x][2]
    edge = vec[x][1]
    selectTouch ='SELECT ST_Touches((SELECT ST_Line_Substring("Xarxa_Prova"."the_geom",0,'
    selectTouch +=str(fraction)+') AS geom FROM "Xarxa_Prova" WHERE"id"='+str(edge)+'),'
    selectTouch +='(SELECT the_geom as geom FROM "Xarxa_Prova" WHERE "id"='+str(edgeAnt)+'));'
    try:
        cur.execute(selectTouch)
        resposta = cur.fetchall()
        conn.commit()
    except:
        print ("SELECT TOUCH ERROR")
    if edgeAnt != -1: 
        if resposta[0][0]:
            updateSegment +='UPDATE"SegmentsFinals" sf SET "cutEdge" = '
            updateSegment +='ST_Line_Substring(s."the_geom",0,'+str(fraction)+') '
            updateSegment +='FROM "Xarxa_Prova" s '
            updateSegmnet +='WHERE sf."edge"='+str(edge)+' AND s."id"='+str(edge)
            updateSegment +=' AND sf."routeid" = '+str(vec[x][0])+';\n'
        else:
            updateSegment +='UPDATE "SegmentsFinals" sf SET "cutEdge" = '
            updateSegment +='ST_Line_Substring(s."the_geom",'+str(fraction)+',1) '
            updateSegment +='FROM "Xarxa_Prova" s '
            updateSegment +='WHERE sf."edge"='+str(edge)+' and s."id"='+str(edge)
            updateSegment +=' and sf."routeid" = '+str(vec[x][0])+';\n'
    else:
        if ordre == 1:
            fractForward = vec[x+1][3]
        else:
            fractForward = vec[x-1][3]
        if fraction >= fractForward:
            updateSegment +='UPDATE "SegmentsFinals" sf SET "cutEdge" = '
            updateSegment +='ST_Line_Substring(s."the_geom",'+str(fractForward)+','
            updateSegment +=str(fraction)+') FROM "Xarxa_Prova" s '
            updateSegment +='WHERE sf."ordreTram" = '+ str(ordre)+' and sf."edge"='
            updateSegment +=str(edge)+' and s."id"='+str(edge)+' and sf."routeid" = '
            updateSegment +=str(vec[x][0])+';\n'
        else:
            updateSegment +='UPDATE "SegmentsFinals" sf SET "cutEdge" = '
            updateSegment +='ST_Line_Substring(s."the_geom",'+str(fraction)+','
            updateSegment +=str(fractForward)+') FROM "Xarxa_Prova" s '
            updateSegment +='WHERE sf."ordreTram" = '+ str(ordre)+' and sf."edge"='
            updateSegment +=str(edge)+' and s."id"='+str(edge)+' and sf."routeid" = '
            updateSegment +=str(vec[x][0])+';\n'

try:
    cur.execute(updateSegment)
    conn.commit()
except:
    print ("UPDATE TABLE SegmentsFinals Geometries ERROR")

Se añade y se actualiza el campo de geometría en la tabla “Resultat”.

alter = 'ALTER TABLE "Resultat" ADD COLUMN newEdge geometry;\n'
alter += 'UPDATE"Resultat" r SET newedge = s.the_geom FROM "Xarxa_Prova" s WHERE s.id = r.edge;'

try:
    cur.execute(alter)
    conn.commit()
except:
    print ("ALTER and UPDATE TABLE Resultat Geometries ERROR")

Acto seguido se actualizan los tramos recortados en la tabla “Resultat”.

update = 'UPDATE "Resultat" r SET newedge = s."cutEdge" FROM "SegmentsFinals" s '
update += 'WHERE s."routeid" = r.routeid AND s.edge = r.edge;'
try:
    cur.execute(update)
    conn.commit()
except:
    print ("ALTER and UPDATE TABLE Resultat Geometries ERROR")

Se seleccionan los N caminos más próximos a la dirección indicada en función del límite introducido por el usuario.

limit = self.getLimit()
select ='SELECT e."'+ nomCamp[0][0] +'" AS NomEntitat, r.agg_cost AS Cost, r.entitatID '
select +='FROM "Resultat" r JOIN "' + self.dlg.comboCapaDesti.currentText()
select += '" e ON r.entitatID = e.id WHERE r.edge = -1 ORDER BY 2 ASC limit ' + str(limit) + ';'
try:
    cur.execute(select)
    vec = cur.fetchall()
    conn.commit()
except:
    print ("SELECT resultats ERROR")

Finalmente se borrará y se creará una tabla para obtener todos los tramos para cada camino óptimo escogido y, al mismo tiempo, se añade la información obtenida en el SELECT anterior.

createTrams = 'DROP TABLE IF EXISTS "TramsNous_'+Fitxer+'";\n'
createTrams += 'CREATE TABLE "TramsNous_'+Fitxer+'" AS SELECT * FROM (\n' 
rowCount = self.dlg.taulaResultat.rowCount()
self.dlg.taulaResultat.setColumnCount(2)
self.dlg.taulaResultat.setHorizontalHeaderLabels(['Entitat', lbl_Cost])
if self.dlg.comboCost.currentText() == 'Distancia':
    rnd = 0
else:
    rnd = 1
for x in range (rowCount,len(vec)):
    self.dlg.taulaResultat.insertRow(x)
    self.dlg.taulaResultat.setItem(x, 0, QTableWidgetItem(str(vec[x][0])))
    self.dlg.taulaResultat.setItem(x, 1, QTableWidgetItem(str(round(vec[x][1],rnd))))
    if x < len(vec) and x >= 1:
        createTrams += 'UNION\n'

    createTrams +='SELECT entitatid, \'' + str(vec[x][0].replace("'","''"))
    createTrams +='\' AS "NomEntitatDesti" ,'+str(round(vec[x][1]))
    createTrams +=' AS agg_cost, ST_Union(newedge) AS the_geom from "Resultat" '
    createTrams +='WHERE entitatid = '+str(vec[x][2])+' GROUP BY entitatid\n'
createTrams += ")total ORDER BY agg_cost ASC;"
QApplication.processEvents()
try:
    cur.execute(createTrams)
    conn.commit()
except:
    print ("create trams ERROR")

A partir de este punto, lo único que quedará por hacer es presentar en pantalla el resultado.

Conclusión

Como conclusión final del post, cabe destacar que este método permite mejorar y refinar el resultado que se obtiene de una de las funciones de la librería pgrouting. De este modo, se ha podido conseguir que al calcular la distancia más corta de uno a varios puntos se obtenga el punto de segmento concreto en el cual se encuentra el inicio o el final, en vez de quedarse simplemente con el nodo más cercano a dichos puntos.

Exemple d’aplicació del mòdul ‘ActualitzaGTC’

Anteriorment l’Ignasi Argemí ja va fer una entrada explicant el funcionament del mòdul ‘Actualitza GTC’ que serveix per facilitar la modificació del GTC, fent una generació, revisió i validació automàtica del graf. Un cop validat la segona part del procés és un ‘batch’ que s’executa diariament en el servidor on es donen valors als atributs necessaris per els ‘encaminaments’ per distància i per temps. Un cop fet això es produeix a l’actualització automàtica del dos fitxers del graf, segments i nodes en el servidor de Postgres.

Ara es veurà un exemple d’aplicació d’aquest mòdul. Suposem que hi ha un GTC, que es vol modificar, s’inicia ‘ActualitzaGTC’, surt el formulari de la figura 1, escollim una connexió i premem el botó ‘CARREGAR GTC’, es demana fixar una contrasenya si és la primera vegada que el volem modificar, o posar la contrasenya ja escollida si ja l’havíem començat a modificar abans.

ActGTC2

Fig. 1. Formulari del mòdul: ActualitzaGTC

Es presenten els segments del graf actual (en realitat una còpia del mateix) i es pot procedir a fer les modificacions que calguin. Ens centrarem en una petita zona del graf. Vegeu la figura 2.

 


 


 


Fig. 2. GTC carregat per modificar. Fem zoom al requadre

Per veure les característiques s’han incorporat també els nodes i les etiquetes identificatives de cada node, també en els segments hi ha indicat a més a més de l’Id del segment el node origen i el node final, representats d’aquesta manera ‘origen/final’. Aquesta informació topològica es pot veure en la figura 3. (Per veure-ho millor cliqueu sobre la figura)

Fig. 3. Zona ampliada del GTC amb informacions de cada capa nodes i segments

Si es mostra la informació del segment 583 tenim el que es veu a la figura 4

Fig. 4. Taula d’atributs inicials del segment 583

Si es fan el canvis desitjats, suposem que la nova topologia queda així, tal com es veu a la figura 5, amb dos segments nous i dos nodes nous

Fig. 5. Nous segments dibuixats amb les eines del QGIS

Un cop fetes les modificacions s’ha de prémer el botó ‘VALIDAR GTC’ i al final si no hi ha errades es veurà el text indicat en la figura 6. Aleshores ja s’han incorporat els segments nous i s’han generat els nusos corresponents.

ActGTC10

Fig. 6. Missatge de GRAF VALIDADAT

Vegeu ara la figura 7 amb les noves etiquetes, allà es pot veure que els segments nous són els que tenen identificadors 3266 i 3264, també hi ha un node nou, el node 5, conseqüència d’haver dividit el segment que inicialment es deia 2266, en dos nous segments anomenats ara 3265 i 2266

Fig. 7. Graf modificat amb les etiquetes de nodes i segments

Ara el nou graf ja està construït nomes falta actualitzar els atributs segons el model de desplaçaments de vianants o de vehicles que s’utilitzi. Això es fa en un procés ‘batch’ un cop cada dia si s’han generats GTC geomètricament diferents. Es mostren ara els atributs dels segments 583 i 3266 en les figures 8 i 9

Fig. 8. Atributs finals del tram 583

 

Fig. 9. Atributs finals del tram 3266

Com es pot  veure els atributs pel segment ja existent són els mateixos, només canvien el nodes inicial i final, fruit de la renumeració, i pel segment nou s’han generat els atributs nous que li corresponen.

D’aquesta manera s’ha pogut veure la facilitat de modificació del GTC que aporta aquest mòdul. La part directa del dibuix depen de les possibilitat d’edició del QGIS, però tota la resta, que consisteix en convertir el nou dibuix en un graf útil des de tots els punts de vista, validació, generació de les dependències entre nodes i segments i actualització dels atributs d’ambdós elements es pot fer de forma senzilla.

ZI-Graf de Trams de Carrer: Anem en la bona direcció

 

Un dels elements diferencials en els aplicatius del CCU, que anomenem ‘mòduls’, és la importància que hi donem al Graf de Trams de Carrer (GTC). Ja abans quan estàvem treballant en l’entorn del GeomediaPro i amb la llibreria del Geomedia Transportation Manager, com avui dia en que treballem amb l’entorn del QGIS.

Fig 1. Desplegament en arbre seguint el GTC. GeomediaPro.

Aquest fet, el treball amb el GTC, s’ha traduït amb la definició de zones d’influència a par-tir del GTC desplegat en arbre a partir d’un punt determinat (vegeu la figura 1) , també anomenat ‘cobertura’ en altres entrades en aquest Bloc, i en la cerca de camins (més curts o més ràpids) a un nombre determinat d’entitats seguint el GTC.

Aquest tipus de zones d’influència graf (ZI-GTC) en les versions del QGIS anteriors a la versió 3 es feia en el servidor PostgreSQL a través de la llibreria ‘pgrouting’, i per definir la ‘cobertura’ a partir d’un punt es va haver de desenvolupar un procediment específic ja que directament en la llibreria no estava implementat. Això està explicat en detall en l’entrada a aquest bloc anomenada: ‘Cobertura mitjançant graf de trams de carrers (GTC)’ publicat per en Josep Lòpez Xarbau el dia 1/06/2017. Vegeu a la figura 2 una mostra del resultat final de la cobertura a partir d’un punt.

Fig 2. Cobertura a partir d’un punt implementat sobre ‘pgrouting’ per en Josep L. Xarbau

Tan en la figura 1 com en la figura 2 es important destacar que un cop assolida la distancia màxima o la funció de cost màxima ens podem trobar en un punt intermig d’un dels seg-ments del GTC, el càlcul d’aquests darrers fragments perifèrics de tram comporta un càlcul especial, com s’explica en el ‘post’ d’en Josep L.Xarbau.

A partir de la versió 3 del QGIS ens trobem que moltes d’aquestes funcions relacionades amb el GTC, com pot ser l’’encaminament’ o cerca d’un trajecte entre punts del mapa i la ‘cobertura’ o desplegament en arbre a partir d’un punt seguint el GTC, estan ja imple-mentades. Desplegant el menú ‘Procesos’->’Caja de herramientas de Procesos’ tal com es pot veure en la figura 3

Fig 3. Eines d’Anàlisi de Xarxes del QGIS v3

En aquest cas la ‘cobertura’ l’anomenen ‘Àrea de Servei’. La implementació de aquestes funcions en els mòduls del CCU, concretament en el mòdul CTE està descrita en l’entrada: ‘Implementación de las funcionalidades QGIS3 para realizar el cálculo local en el módulo CTE’ d’en Manuel Duro.

Val a dir que un cop obtingut el desplegament en arbre a partir d’un punt s’ha de definir un ‘buffer’ a l’entorn d’aquesta entitat lineal i això constituirà la nova zona d’influència d’aquest punt seguint el GTC.

Plantejat tot això diem que anem en la bona direcció per que l’evolució de les eines del QGIS sembla indicar-ho així, dotant al seu aplicatiu d’uns recursos analítics que en versions anteriors no hi eren i que entre altres àmbits impliquen a tot el que te a veure amb el GTC, és a dir l’encaminament i la ZI-GTC. El projecte CCU sempre ha apostat per aquests plantejaments i ha treballat en la generació de mòduls relacionats amb el GTC, ara l’evolució de la tecnologia encara reforça mes aquest enfocament.

De totes maneres l’avantatge o inconvenient de realitzar els càlculs dels camins o les ZI seguint el GTC en el propi equip o fer-ho en el servidor PostgreSQL requereix un estudi de mes profunditat. El que sí està clar és que la flexibilitat en poder escollir un procediment o un altre reverteix en benefici de l’usuari, que podrà aprofitar ambdós mètodes per treure’n més rendiment al seu equip.

Manual d’ús de l’usuari: Cerca de trajectes a entitats

Aquest document explica el funcionament del mòdul de ‘Cerca de Trajectes a Entitats’ per a QGIS. Aquest mòdul permet obtenir els trajectes o camins entre una adreça qualsevol de Mataró entrada per l’usuari i les N entitats més properes (també escollides per l’usuari). El cost pot estar en funció de la distància o el temps. Els desplaçaments obtinguts es mostren de forma ordenada de menys a més cost en forma de taula i de capa. Per a poder utilitzar-lo, el primer que s’ha de fer és executar el programa QGIS i un cop inicialitzat aquest, cal pitjar la icona següent CTE2o anar a Complementos -> CCU -> Cerca de Trajectes a Entitats i s’obrirà una finestra com la que podem veure a continuació a la figura 1.

CTE1

Figura 1: Imatge de l’estat inicial del mòdul CTE

Aquest mòdul es pot dividir bàsicament en tres parts diferenciades: origen (1) , destí (2), connexió i botons (3).

1. Connexió i altres botons

La primera part a mostrar inclou els botons de funcionament del mòdul (d’esquerra a dreta):

  • Connexió: pestanya desplegable on es mostren totes les connexions.
  • Botó ‘Inici’: aquest botó inicia el procés de consulta del mòdul.
  • Botó ‘Sortir’: aquest botó tanca el mòdul.

CTE5

Figura 2: Connexió i botons

2. Origen

En aquesta part del mòdul l’usuari troba les eines per escollir el punt d’inici, més concretament l’adreça. Seguidament es descriuran les seves parts, començant per la part superior:

CTE3

Figura 3: Origen

El primer element que trobem és una camp de text per cerca el nom del carrer a on es troba l’origen. Inicialment, en el gran requadre inferior, s’hi llisten tots els noms de carrers i a mesura que es va introduint un nom, la llista es va actualitzant automàticament amb els noms que s’assemblen al nom que introdueix l’usuari fins a trobar el desitjat. Una vegada, s’ha trobat el carrer, cal fer doble clic en el nom perquè quedi ben especificat en el camp de text.

Posteriorment, s’ha d’escriure el número del portal que desitgem, juntament amb la lletra. En el cas de la lletra no és necessari escollir-ne una.

Per acabar, a la dreta del camp de text per introduir el nom hi ha un botó amb una creu (X) que permet esborrar el contingut del camp de text.

3. Destí

En aquesta part del mòdul, l’usuari pot escollir la capa de destí i les diferents característiques dels camins: cost, número de camins i aproximació en cas de no existir l’adreça desitjada.

Començant per la part superior, el primer que trobem és una pestanya desplegable on es mostren les diferents capes de punts que poden ser destí. Just a sota hi trobem els modes de cerca. El primer que trobem són dos botons, de color verd i vermell respectivament.

El botó “Més proper” escull l’adreça amb el número de portal més proper a la adreça que s’ha seleccionat, independentment de si és parell o senar, i sempre que l’adreça escollida per l’usuari no existeixi.

En canvi, el botó “Més proper Parell/Senar” escull el portal amb el número senar o parell en funció de quin dels dos tipus sigui el número que s’hagi escollit prèviament, i sobretot que no existeixi.

A la dreta d’aquests dos botons, hi ha una spin box que permet escollir el nombre de camins desitjats, en un rang de 1 a 10 camins. En el cas que el nombre de camins sigui superior al nombre d’entitats d’una capa, el número de camins serà tants com entitats tingui la capa escollida.

Després trobem una pestanya desplegable on es pot triar el cost dels camins: distància o temps. En el cas d’escollir la opció de temps, hi ha un check box que permet incloure en el cost el cost de nusos.

A sota hi ha un gran requadre que s’utilitza per mostrar els resultats de la cerca que s’ha realitzat. La taula que es mostra té dos columnes: la primera mostra el nom de l’entitat de destí i la segona mostra el cost: si és distància en metres i si és en temps en minuts.

Entre la opció del cost i el requadre de resultats hi ha un espai buit que un cop s’ha fet la consulta hi apareix l’adreça de l’origen.

CTE4

Figura 4: Secció de destí

Estudi de l’Activitat Econòmica

 

Unes de les aplicacions més sol·licitades dels Sistemes d’Informació Geogràfica (SIG) són les que tenen a veure amb l’anàlisi de l’activitat econòmica (AE), sigui aquesta la corresponent d’una ciutat, d’un territori o d’un país.

De fet la col·locació sobre el terreny de les diferents activitats econòmiques és una informació estratègica de primer ordre, ja que d’una mirada es pot intuir  si d’una determinada activitat, diguem-ne per exemple: restaurants, farmàcies o perruqueries, n’hi ha una concentració exagerada, equilibrada o deficient. Una anàlisi més rigorosa ens permetria saber si d’acord amb la població ‘target’ que hi ha en la seva proximitat i amb els hàbits de mobilitat de la població està justificada o no una determinada oferta en un lloc concret en relació amb la demanda possible. En aquest sentit s’hauria d’anar a esbrinar motivacions sociològiques, moltes vegades difícilment  racionalitzables, per explicar el per què de la presència o no  d’una activitat en una àrea determinada.

De tota manera, una de les motivacions més senzilles de la geolocalització d’activitats econòmiques en un territori, serien les aplicacions anomenades de ‘geo-marketing’, consistents en veure on hi ha ‘buits’ o mancances d’una determinada activitat per impulsar la creació de negocis precisament en aquells indrets.

Un primer punt d’un aplicatiu que respongués a tals característiques seria la ubicació de les activitats econòmiques sobre el mapa de la ciutat, en aquest cas, de la ciutat de Mataró. Aquesta eina per ser útil caldria que oferís la possibilitat de diferents mètodes de cerca de les activitats, sigui pel nom o descripció, sigui pel codi corresponent segons una determinada classificació. També caldria tenir una font de les activitats i un manteniment que permetés afegir amb agilitat les altes i les baixes que es van produint.

Arribats a aquest punt cal dir que el CCU ha treballat i està treballant en la generació d’eines que permetin ubicar les AE sobre el mapa de la ciutat de Mataró, tant pel que fa a parcel·la com a portal.

La font  de la informació de l’AE de Mataró que ha escollit el CCU és la Brossa Comercial (BC). Cada activitat genera un tipus de deixalles específic i això influeix en la tarifa que ha de pagar, i quan es deixi de fer l’activitat el seu titular serà el primer interessat en notificar-ho als responsables de recaptació per deixar de pagar per aquell concepte, per tant la Base de Dades de la Brossa Comercial és una font actualitzada de l’AE a la ciutat. Com a part negativa d’escollir aquesta font hi ha el fet  que l’activitat real que es faci no s’ajusti exactament a la declarada en concepte de deixalles generades.

Respecte al tema de la classificació, en aquest moment s’ha escollit la forma de classificació que la BC utilitza, que és la dels epígrafs de l’antic IAE (Impost sobre l’Activitat Econòmica), amb tendència a anar-ho canviant progressivament cap a la classificació CCAE (Classificació Catalana d’Activitats Econòmiques).

A l’aplicatiu del CCU també es poden visualitzar algunes característiques concretes com ara la superfície de l’activitat i consultar igualment algunes informacions proveïdes per la Base de Dades de la BC. A més a més també es poden consultar d’altres informacions relacionades amb la població que s’aniran explicant tot seguit i que el refermen com a eina analítica a més a més d’informativa.

Anem a concretar una mica tot això. A la figura 1 es pot veure la interfície on hi el cercador on a partir d’un paraula o conjunt de paraules o d’un codi podem anar seleccionant les activitats que es volen mostrar.

Fig 1. Llista d’activitats que podem cercar i seleccionar

Un cop escollida l’activitat, si es tracta de situar els portals on es desenvolupa l’activitat, es pot anar a una altra pestanya per incidir en el tamany del ‘topo’ on es mostra (proporcional a la superfície del local), i fer d’altres mesures relacionades amb la població, com ara definir una zona d’influència(ZI) a l’entorn de la ubicació de cada activitat i mostrar un mapa temàtic de la població que queda fora de aquestes zones d’influència.

Si mirem per exemple les ferreteries, la segona pestanya seria la que mostra la figura 2

Fig 2. Pestanya pes escollir tamany dels ‘topos’ i de la Zona d’Influència i tipus de Z.I

En aquest cas s’ha escollit un factor de forma dels ‘topos’ de 2, àrees d’influència circulars de 150 m de radi i veure el mapa temàtic de la població exclosa. La sortida es mostra a la figura 3 on s’ha fet un zoom sobre el centre urbà de la ciutat i es poden apreciar els indrets de l’activitat, les  ZI circulars i el mapa temàtic de les illes externes a les ZI.

Fig 3. Ferreteries amb ZI de 150 m i temàtic de població exterior

La llegenda corresponent a aquest mapa es mostra a la figura 4:

Fig 4. Llegenda del mapa de ferreteries

En el mapa temàtic de la població, les Illes més fosques corresponen a les de més població i per tant allà on ‘faria més falta’ la instal·lació de noves activitats.

Les ZI es poden escollir també sobre el Graf de Trams de Carrer (GTC), anem a  veure un altre exemple, les farmàcies.

En aquest cas hi ha la possibilitat d’escollir el treballar amb distància o recorregut seguint el GTC o bé amb temps de trajecte, i s’ha triat una zona d’influència de 3 minuts a l’entorn de cada centre d’activitat. La segona pantalla es mostra a la figura 5 i la sortida a la figura 6

Fig 5. Segona pantalla per a les Farmàcies amb ZI-GTC

Fig 6. Sortida de la consulta de Farmàcies amb ZI graf a 3 minuts

En resum la interacció entre la situació de les diferents activitats econòmiques amb la població, segmentada per Illes, permet veure la sobre-presència d’activitats en uns punts de la ciutat així com la no presència en d’altres on hi pot haver potencials usuaris o compradors. També la utilització del graf de trams de carrer graduat per distància o per temps ens dóna una idea molt fidel del concepte de proximitat i ens permet fer un anàlisi més acurat de les necessitats o tendències properes en la instal·lació de noves activitats.

 

 

 

 

 

 

 

Sobre el Graf de Trams de Carrer (GTC)

 

Tal com ja s’ha comentat en aquest bloc quan hem parlat del ‘Nou concepte de Zones d’Influència’, un element bàsic de la modelització dels desplaçaments a la ciutat de Mataró és el Graf de Trams de Carrer (GTC). Aquest graf està format per segments i nodes, cada segment és un tram de carrer (part del carrer entre cruïlles) i els nodes són precisament les cruïlles.

El GTC es pot obtenir de moltes maneres, però en resum hi ha dos orígens bàsics, ad­quirint-lo a una empresa especialitzada (com per exemple Navteq o  TomTom) , on s’inclouran informacions sobre els sentits de circulació en cada via i els girs prohibits i autoritzats en cada nus i moltes altres coses, o bé generant-lo nosaltres mateixos, aquí s’ha optat pel segon cas, més que res per que es vol estudiar més el desplaçament de vianants  que no pas el de vehicles i d’aquesta manera podem afegir i incloure en el GTC trams que no siguin vials de carrer, com ara camins de vianants dins de parcs o zones verdes i recorreguts específics de la gent que va a peu.

Des del punt de vista d’un SIG el GTC està format per un conjunt d’entitats, o classe d’entitat, segons la terminologia del GeoMedia, de tipus lineal, els segments del graf, i un conjunt d’entitats de tipus punt, els nodes. Aquestes entitats lineals han de ser total­ment connexes si es vol navegar al seu través, o sigui, no hi pot haver cap punt de des­connexió o discontinuïtat. També a part de les característiques geomètriques de cada classe d’entitat, línies i punts, cal que hi hagin uns atributs associats a cada element si­gui aquest segment o node.

Quins són aquests atributs?

En primer lloc hi ha d’haver un codi per a cada segment i un codi per a cada node aquests dos codis han d’estar relacionats, és a dir,  dins de cada segment hi ha d’haver informació d’entre quins dos nodes està definit aquell segment en concret, i això per a tots els segments, d’aquesta manera amb aquestes dues llistes la de segments amb els codis dels nodes dels extrems de cada segment i la dels nodes s’estableix la morfologia del graf i es podria calcular una ruta encara que no tinguéssim la imatge geomètrica precisa.

Un altre atribut que podem tenir dins de la taula de segments és sobre l’ orientació o sentit del tram, aquesta orientació és arbitrària i s’agafa en el moment de definir el graf, per tant ens cal saber quin és el node d’origen del tram i quin el node de final del tram, per tant aquests nodes extrems del tram no són qualssevol , un d’ells és des de on parteix el tram i l’altre és a on arriba.

Per la construcció del GTC utilitzem una eina del GeoMedia Transportation Manager que parteix d’una classe d’entitat lineal i ella mateixa et va guiant per acabar obtenint les dues classes d’entitat del graf, els segments i els nodes, automàticament és generen els camps: NodeId en la taula de nodes amb un codi per cada node, i els camps: EdgeId, FromNodeId, ToNodeId en la taula de segments, que ens indiquen el codi de segment, i des de quin node a quin altre node està definit el segment, respectivament. Aquests són els camps principals per la construcció del graf, després n’hi ha uns altres que anirem comentant a continuació. Vegeu a la figura 1 una part dels segments i els nodes del GTC amb els identificadors respectius.

Fig1. Segments i Nodes del GTC amb els codis de EdgeId (vermell) i NodeId (negre)

Si cliquem sobre del tram 1017 obtenim les informacions que es mostren a la figura 2, on es poden comprovar els valors dels atributs EdgeId, FromNodeId i ToNodeId i es pot veure que el tram 1017 efectivament va del node 836 fins al node 837 tal com es veu a la figura 1.

Fig2. Dades del Segment 1017

De la mateixa manera es pot comprovar que hi ha molts altres camps dins dels atributs del tram, fixem-nos de moment en els camps LENGTH i Cost i Cost_invers.

Per què volem el GTC?

Per a dues coses, en primer lloc per a navegar des d’un punt de la ciutat fins a un altre, aquesta navegació ens ha de portar al conjunt de segments concatenats que uneixin el punt inicial amb el punt final segons un determinat criteri d’optimització que podria ser minimitzant la distància o minimitzant alguna altra variable (a la figura 3 es mostren els trajectes a les 3 Escoles Bressol més properes des d’una adreça concreta de la ciutat)  i en segon lloc per desplegar a partir d’un punt el conjunt, ramificat en arbre, de trajectes fins a assolir una determinada distància màxima o un valor màxim d’un altre indicador (vegeu la figura 4)

Fig 3. Trajectes a les 3 Escoles Bressol més properes des d’un punt de la ciutat seguint el GTC. La variable a optimitzar és la distància.

A la figura 4 es pot veure aquesta construcció en arbre, seguin el GTC, a partir de l’entitat: Escola Bressol ‘Les Figueretes’ fins a una distància màxima de 250 m. Com es veu a la figura la progressió fins a assolir els 250 metres pot acabar en un punt entremig del tram.

Fig 4. Arbre corresponent a l’Escola Bressol ‘Les Figueretes’ sobre el GTC (segments i nodes) fins a una distància de 250 m.

Tant en el cas 1, camí o trajecte entre dos punts de la ciutat, com en el cas 2, arbre des­plegat sobre el GTC a partir d’un punt, s’ha utilitzat la distància, el camp LENGTH, de cada segment com a base dels càlculs, això vol dir el camí òptim de distància mínima entre dos punts o el desplegament per la xarxa de trams de carrer fins arribar a fer la distància fixada de 250 m.

Una altra possibilitat seria fer servir una altra variable a minimitzar quan volem definir un camí o a utilitzar quan volem definir un desplegament en arbre, aquesta variable se­ria la que tenim quantificada en els camps Cost i Cost_invers de cada tram. Així com la longitud del tram no depèn de si es recorre en un sentit  o en un altre, en canvi si es tre­balla amb una altra variable, com ara el temps de recorregut del tram, sí que depèn de les característiques específiques de cada tram, com ara el pendent, els obstacles i la ti­pologia (plataforma única, escales, etc.) i en aquest cas té sentit de tenir dos paràmetres per tram, per si es circula en el sentit definit del tram Cost o si es va en sentit contrari Cost_invers. Això pot donar lloc a diferències importants de recorregut o de conjunt de carrers a l’abast si es va de casa a l’Ambulatori o es torna de l’ambulatori, sobretot quan el terreny és accidentat, amb moltes pujades i baixades.

En resum, quan més acurada sigui la informació del GTC, i en concret de cada tram, més es podrà afinar en la cerca de recorreguts òptims i en la definició de les Zones d’Influència a través del graf. De la mateixa manera, la utilització de la variable temps com a funció de cost, ens dona una mesura molt més real de la proximitat o llunyania dels centres proveïdors de serveis al ciutadà però requereix de tenir un bon model de la velocitat en els desplaçaments.

Relació entre la capacitat d’un centre proveïdor de serveis i la seva àrea d’influència

 

Ja s’ha vist, en aquest mateix Bloc, com associar la població amb el territori, sabem que pot quedar associada a les Illes, parcel·les i els portals de la ciutat, i també s’ha vist com segmentar aquesta mateixa població segons determinats criteris, franja d’edat, estudis, procedència geogràfica, nacionalitat etc.

Ara anem a explicar com donat un determinat centre proveïdor d’un servei, per exemple un centre educatiu,  podem delimitar una zona del territori immediatament proper, de manera que ‘casin’ la capacitat del centre per una part i la població ‘target’ d’aquest zona propera per altra.

No cal dir que la vista del territori estudiat, en aquest cas la ciutat de Mataró, amb els centres proveïdors  del servei i les respectives àrees properes d’influència, pot donar una imatge, al menys teòrica, de la cobertura o no cobertura de les necessitats del global de la població en el servei objecte d’estudi.

Des d’un punt de vista tecnològic, és a dir, de les eines que ens poden permetre obtenir aquesta representació gràfica, un SIG (Sistema d’Informació Geogràfica) per sí mateix no ens permet obtenir-ho d’una forma fàcil i immediata. Per tant hem hagut d’anar a les funcionalitats base del nostre SIG, en aquest cas el GeoMedia, per generar un procés iteratiu i convergent de modificació de la zona d’influència fins que el nombre d’habitants continguts a la zona, coincideixi amb la capacitat de servei del centre estudiat.

Anem a veure-ho per un cas concret que coneixem. Suposem que volem estudiar la implantació de les Escoles Bressol Municipal a la ciutat de Mataró, recordem la situació dels centres en la figura 1.

Fig 1. Situació de les Escoles Bressol Municipals a la ciutat de Mataró.

Ja que els usuaris de les Escoles Bressol són nens entre 0 i 2 anys, el que s’ha de fer és preparar una segmentació de la població total que només tingui en compte aquesta franja d’edat, i també s’ha d’escollir si ho agreguem per Illes, parcel·les o portals. Utilitzarem el recurs basat en Visual Basic que ja vam explicar, la interfície seria la de la figura 2.

Fig 2. Escollim els habitants entre 0 i 2 anys agrupats per Illes.

Això vol dir exactament que tenim associat a cada illa de cases el nombre de nens entre 0 i 2 anys que hi ha empadronats en algun habitatge de l’illa. Ens cal també tenir associat a cada entitat Escola Bressol el nombre màxim de nens que pot acollir. A partir d’aquestes dues dades podem iniciar el procés de càlcul pròpiament dit. Cal tenir en compte que l’àrea d’influència resultant serà, probablement, diferent per a cada entitat ja que dependrà tant de la capacitat del centre com de la densitat que hi hagi a les illes del voltant de cada centre de nens entre 0 i 2 anys.

Fixem-nos en la interfície de càlcul de les Àrees d’Influència de la figura 3, aquí podem veure el formulari que s’ha d’omplir per iniciar el càlcul.

Fig 3. Interfície per generar les Àrees d’Influència

Els camps més importants són:

Tipus d’agregació: ILLES [podrien ser també Parcel·les o Portals]
Entitat Base: Escoles Bressol [a partir de les quals generem les Àrees d’Influència]
Paràmetre del Radi Incial: 400 [valor associal al radi de les Zones d’Influència incials]
Cobertura: 100% [si volem que Tota la població del rang tingui Escola Bressol, o només una part, en aquest cas aquest valor seria de menys del 100%]
Possibilitat de comptar els habitants que no estàn a cap zona: Sí
Possibilitat de fer un mapa temàtic de la població no inclosa: No
Treballar per Trams: No [Possibilitat d’agafar Zones d’Influència Circulars o a partir del Graf de Trams de Carrer]

Si premem el botó de ‘Calcular l’Àrea d’Influència’ obtenim el que surt a la figura 4.

Fig4. Àrees d’Influència de les EB Municipals

A l’anterior figura es pot veure l’Àrea d’Influència de cada Escola Bressol Muncipal on s’ha aproximat la població entre 0 i 2 anys de cada zona i la disponibilitat de places de cada centre. Encara que no es vegi a la figura 4, s’ha calculat igualment el  nombre de nens d’aquestes edats que queda fora del conjunt d’àrees, que és per a tota la ciutat de 1972. Cal pensar també que segons la mena d’agregació que es faci l’aproximació entre la xifra del recompte de nens dins de la zona i la del nombre de places serà més o menys propera, si comptem per illes l’error que es pot cometre és molt més gran que si comptem per parcel·les o portals, ja que a l’incloure o no una illa el nombre d’habitants de la zona canvia molt bruscament.

També hi ha la possibilitat de fer un mapa temàtic de tota aquesta població que queda fora, d’aquesta manera les illes més fosques són les que tenen més nens ‘exclosos’ en la situació actual de les Escoles Bressol Municipals i considerant una cobertura del 100%. Vegeu la figura 5.

Fig 5. Àrees d’Influència de les EB Municipals, amb mapa temàtic per illes de la població exclosa

Es imporant pensar que el que s’ha vist per les Escoles Bressol Municipals, es pot generalitzar a qualsevol grup d’entitats que ofereixin un servei determinat i de les que coneixem la seva capacitat en el servei, per exemple els Centres d’Assistència Primària, els Centres Cívics, les institucions socio-sanitàries, etc.

En un cop d’ull, si mirem per exemple la figura 5 podem saber a quins llocs de la ciutat seria més interessant que hi hagués un nou centre o a on no caldria que n’hi hagués un d’existent. L’eina permet fer simulacions modificant la ubicació i la capacitat d’un centre en concret observant com varien el nombre i distribució de la població no inclosa.

Igualment tot el que s’ha fet per les Àrees d’Influència circulars, a vista d’ocell, es pot fer també per les Àrees d’Influència seguint el Graf de Trams de Carrers, considerant els trajectes del vianants i donant una imatge més real de la capacitat d’accedir a un determinat servei.  Però això ja ho comentarem més endavant.

Nou concepte de Zones d’Influència lligat als desplaçaments de la població

 

Tots els Sistemes d’Informació Geogràfica (SIG) tenen el concepte de Zona d’Influència, normalment anomenat ‘buffer’, que consisteix en agafar una classe d’entitat (taula d’entitats) i generar en el seu entorn una àrea que amplia la frontera de les entitats una certa distància i respon a la idea de zona d’influència o zona de proximitat o de veïnatge.

Per tant si la classe d’entitat de la que volem definir el ‘buffer’ és una àrea, tal com hem dit, el seu ‘buffer’ és una altra àrea que comprèn l’entitat i té més o menys la mateixa forma, però si la classe d’entitat és lineal el seu ‘buffer’ és una àrea de tipus rectangular que pot estar arrodonida en els extrems  i si la classe d’entitat és puntual el seu ‘buffer’ és una àrea de tipus circular.

Un paràmetre característic de les zones d’influència és el ‘radi’ o distància, en realitat el concepte més adequat és el de distància ja que ens indica a quina distància de l’entitat base es troba el límit de la seva zona d’influència, però que en el cas d’entitats  puntuals, com que la zona d’influència és circular, sí que coincideix amb el radi d’aquest cercle.

Fig 1: Zones d’Influència sobre les Zones Verdes a una distància de 50 m.

A la figura 1 podem veure un exemple de les zones d’influència sobre entitats tipus àrea, com és el cas de les zones verdes accessibles de la ciutat de Mataró, en aquest cas s’ha considerat una distància fixa de 50 metres. Això podria tenir un sentit de comptar , per exemple, quants ciutadans viuen a menys de 50 metres d’una zona verda.

Un altre cas molt comú d’utilització de les zones d’influència seria veure quants ciutadans estan a més d’una determinada distància d’un centre proveïdor de serveis, com un Centre d’Assistència Primària (CAP) o un centre docent o un centre cívic, en aquest cas són molt útils els ‘buffers’ a l’entorn d’aquestes entitats, que normalment són representades com a entitats puntuals i per tant les seves zones d’influència seran circulars. Això ho podem veure a la figura 2 pel cas d’Escoles Bressol Municipals de la ciutat de Mataró.

Fig 2: Zones d’Influència a l’entorn de Escoles Bressol Municipals a 250 m

En aquesta figura es veuen els típics cercles que corresponen a les zones d’influència de les entitats puntuals i que podrien servir, tal com hem dit, per veure quanta població està a menys de 250 metres d’una Escola Bressol Municipal i quanta a més, per exemple.

Aquesta característica de dibuixar ‘buffers’ a l’entorn d’entitats és molt utilitzada en SIG quan es volen fer operacions espacials, com ara unió, intersecció, combinacions analítiques, agregacions etc. En el cas de les Escoles Bressol, es pot fer una agregació de tota la població (o dels infants entre 0 i 2 anys) que hi ha  dins de cada zona d’influència a partir de les dades que tenim prèviament agrupades per Illes de cases, parcel·les o portals, tal com s’ha descrit en un altre ‘post’ en aquest mateix bloc, indicant que es sumen tots els habitants que pertanyen a les entitats (siguin aquestes Illes, parcel·les o portals) que estan contingudes dins de la zona d’influència corresponent.

De totes maneres, en totes les operacions que tenen a veure amb la població i amb els seus desplaçaments per la ciutat, aquesta mesura de la proximitat directe que ens proporciona el ‘buffer’ dels SIG no sempre ens és útil, ja que si volem dir ‘nens que hi ha a menys de 250 m de l’Escola Bressol’ aquest concepte de ‘buffer’ ens mostra els nens que viuen  a menys de 250 m, però en línia recta, ja que és el radi de la zona d’influència. El que seria més real seria indicar els nens que hi ha a 250 m seguint la xarxa de carrers, comptant que els nens aniran a l’escola circulant pel carrer. També seria útil considerar en comptes de distància, el seu equivalent en temps, nens que hi ha a menys de 5 minuts del centre, i en aquest cas tenint en compte les facilitats o inconvenients que presenten els carrers, pendents, obstacles ,escales etc.

Això ens ha de portar a definir una nova zona d’influència lligada a la xarxa de trams de carrer (anomenem tram el segment de carrer entre cruïlla i cruïlla). En primer lloc considerarem la xarxa com a una entitat lineal arborescent que creix a partir de l’entitat puntual origen (en aquest cas serien les Escoles Bressol). Vegeu la figura 3

Fig 3. Graf de Trams de Carrer a partir de les Escoles Bressol fins a 250 m de distància

Efectivament  a la figura es poden veure els recorreguts a partir de l’entitat origen que faria un vianant anant en qualsevol direcció (sense passar dues vegades pel mateix lloc) i recorrent un màxim de 250 metres. Com es pot veure els possibles recorreguts depenen de la morfologia de la xarxa de carrers en cada lloc de la ciutat, a part de la pròpia distància a recòrrer. En aquest cas el sentit de distància és molt més real que considerant les zones d’influència clàssiques amb distància a vista d’ocell.

Com que volem tenir una zona d’influència amb les mateixes característiques que la definida de forma clàssica, hem de convertir aquest conjunt de trams en un àrea, agafant precisament un ‘buffer’ sobre aquesta entitat lineal (abans hem hagut de convertir el conjunt de trams en una entitat lineal única)

Fig 4. Zones d’Influència sobre el Graf de Trams de Carrer, distància 250 m

A la figura 4 es pot veure l’efecte d’agafar un ‘buffer’ sobre cada conjunt de trams desplegats a 250 m de la seva entitat origen. Aquest ‘buffer’ s’agafa a 20 m de les línies del graf de trams.

D’aquesta manera es poden continuar aplicant les operacions espacials que ens calguin pels nostres càlculs com si fossin àrees circulars, però amb l’avantatge d’uns resultats molt més realistes quan treballem amb població i distàncies.