Robitex's Blog

Ideas in the web

Archivi Mensili: luglio 2012

L’Arte della pericolosità sismica – Parte 2


Sommario

Con un nuovo tocco di colore, torniamo sulla mappa della pericolosità sismica italiana per produrre un’altra pagina artistica. Questa volta useremo una scala di colori con quelli della nostra bandiera…

Colore italiano

Riprendendo il codice illustrato in questo post, è sufficiente creare una nuova funzione Lua, riportata in seguito, per ottenere la mappa sottostante:

La mappa di pericolosità sismica in versione tricolore

La mappa di pericolosità sismica in versione tricolore

Il colore, funzione dell’accelerazione, varierà da verde per il valore minimo a bianco per l’accelerazione media, fino ad arrivare al rosso per l’accelerazione massima.
In LaTeX, un colore può essere miscelato facilmente con il bianco specificandone dopo il nome ed un punto esclamativo, un valore variabile da 0 a 100. Il valore nullo corrisponde al colore bianco, mentre il valore 100 lascia intatto il colore.
Così, l’espressione ‘green!50’ corrisponde al colore bianco con il 50% di verde.

Il codice seguente mostra la funzione che genera l’espressione del colore in funzione dell’accelerazione. Valori bassi di pericolosità saranno rappresentati da un colore verde mescolato con sempre meno bianco a mano a mano che l’accelerazione decresce, mentre valori elevati saranno rappresentati da un colore rosso mescolato ad una componente decrescente di bianco:

-- funzione di interpolazione lineare
local function linear(x,x1,x2,y1,y2)
   return y1 + (y2-y1)*(x-x1)/(x2-x1)
end

-- funzione scala di colori dal verde al rosso
-- passando per il bianco
local function green2red(ag)
   local agmean = (agmax+agmin)/2
   local basecol, val
   if ag < agmean then
      basecol = 'green'
      val = linear(ag, agmin, agmean, 100, 0)
   else
      basecol = 'red'
      val = linear(ag, agmean, agmax, 0, 100)
   end
   
   return string.format('%s!%d', basecol, val)
end

Ho stampato anche questa nuova mappa, naturalmente a colori, e l’ho appesa in ufficio a beneficio della collezione primavera estate 2012.
Ciao.

Annunci

L’Arte della pericolosità sismica


Sommario

Attraverso i software del mondo TeX, creeremo una visualizzazione artistica della mappa di pericolosità sismica italiana contenuta nella norma D.M. 14/01/2008. L’elaborazione grafica sarà opera del potente pacchetto TikZ progettato per LaTeX, mentre un piccolo programma in Lua si occuperà della costruzione logica.

Pericolosità sismica S1

Il progetto S1 di INGV, l’Istituto Nazionale di Geofisica e Vulcanologia, recepito poi dalla normativa tecnica, ha definito la pericolosità sismica nel territorio italiano attraverso una griglia di punti distanti uno dall’altro poco più di 5 km.
L’idea è quella di replicare le rappresentazioni grafiche diffuse dall’INGV con gli strumenti del mondo TeX, realizzando mappe a colori con i valori dell’accelerazione di picco al suolo PGA, Peak Ground Accelaration (un risultato è riportato in fondo all’articolo).

Immagine della mappa S1 tratta dal sito INGV

Immagine della mappa S1 tratta dal sito INGV

Struttura del codice

Ecco una descrizione di come verranno elaborati i dati:

  • uno script principale in Lua, efficiente linguaggio di scripting, leggerà i dati della pericolosità producendone un file di testo contenente comandi grafici per TikZ;
  • un sorgente LaTeX elaborerà i comandi producendo la mappa grafica in formato pdf.

I dati

Ho tradotto la tabella scaricabile dal sito del Consiglio dei Lavori Pubblici, contentente i dati di pericolosità sismica, in una forma direttamente comprensibile da Lua: ecco come appare il contenuto del file di dati che ho chiamato ‘GridS1.lua’:

GridS1 = {
[13111] = {lon=6.5448, lat=45.134, Tr30={0.0263, 2.50, 0.18}, Tr50={0.0340, 2.51, 0.21}, ...ecc
[13333] = {lon=6.5506, lat=45.085, Tr30={0.0264, 2.49, 0.18}, Tr50={0.0341, 2.51, 0.21}, ...ecc
[13555] = {lon=6.5564, lat=45.035, Tr30={0.0264, 2.50, 0.18}, Tr50={0.0340, 2.51, 0.20}, ...ecc
...ecc

Creare i comandi grafici

Disegneremo per ciascun punto della griglia S1, un quadratino colorato secondo una data scala di colori associata al valore della PGA, ma per farlo dobbiamo risolvere due problemi:

  • tradurre la coppia longitudine, latitudine dei punti in coordinate nel piano x, y;
  • associare un colore al valore di accelerazione.

Il sorgente Lua mostrato nel seguito dapprima carica in memoria i dati strutturati della griglia, determina i valori minimi e massini dell’accelerazione tra tutti i 10751 punti (per il tempo di ritorno di 475 anni) utili in seguito, poi definisce le due funzioni fondamentali di trasformazione delle coordinate (trasf()) e di associazione valore->colore (wavecolor).

Preparato il terreno, lo script si conclude con la funzione go(), che scrive su un file esterno chiamato defpoint.tex, le istruzioni TikZ di disegno.

Notate che la funzione go() accetta come argomenti anche delle funzioni. Il vantaggio immediato di questo tipo di programmazione disponibile in Lua è che la funzione go() diviene indipendente sia dal tipo di trasformazione di coordinate che dalla scala di colore (io ho scelto di lavorare con la definizione di colore basato sulla lunghezza d’onda della luce con rapporto lineare rispetto alla PGA).

Per i più curiosi, nei commenti del codice sono riportati i due punti della maglia S1 corrispondenti al punto sismicamente più pericoloso e quello meno pericoloso sul territorio della penisola italiana…

-- carica la tabella dati dal file GridS1.lua
dofile "GridS1.lua"

-- funzione di massimo o minimo valore
local function S1(funval, key)
   local rif = funval(GridS1[13111])
   local id

   for idx, t in pairs(GridS1) do
      local val = funval(t)
      if key == "max" then
         if  val > rif then
            rif = val
            id = idx
         end
      elseif key == "min" then
         if val < rif then
             rif = val
             id = idx
          end
       else
          error("The key '"..key"' is not supported.")
       end
    end
    return rif, id
end
-- funzioni di estrazione dati singolo nodo
local function Lat(t)
    return t.lat
end
local function Lon(t)
    return t.lon
end
local function Ag475(t)
    return t.Tr475[1]
end
local function countNode()
    local i = 0
    for _, t in pairs(GridS1) do
       i = i + 1
    end
    return i
end
-- valori minimi e massimi dei dati di mappa
local agmax, idmax = S1(Ag475, 'max')  --> 0.278 , 49640
local agmin, idmin = S1(Ag475, 'min')  --> 0.0364, 12693

-- latitudine
local latmax = S1(Lat, 'max')   --> 47.178
local latmin = S1(Lat, 'min')   --> 36.573

-- longitudine
local lonmax = S1(Lon, 'max')   --> 18.594
local lonmin = S1(Lon, 'min')   --> 6.5448

-- numero nodi S1 (solo per saperlo...)
local numnode = countNode()     --> 10751

-- funzione di servizio
local function makecmdfile(fn, t)
   local outputfile = assert(io.open(fn..".tex","w"))
   outputfile:write(table.concat(t,"\n"))
   outputfile:close()
end

-- restituisce le coordinate di mappa
-- da quelle geografiche
local function trasf(lon, lat)
   -- fattore di conversione gradi->cm
   local f = 4.1

   return 0.80*lon*f, lat*f
end

-- funzione scala di colori wavelets
local function wavecolor(ag)
   local w1 = 363
   local w2 = 814
   local m = 80
   w1 = w1 + m
   w2 = w2 - m
   return w1 + (w2-w1)*(ag-agmin)/(agmax-agmin)
end

-- maschera di formato disegno
local cmask = '\\convertcolorspec{wave}{%d}{rgb}\\col\\color[rgb]{\\col}'
local dmask = '\\draw (%0.3f,%0.3f) node {};'

-- filename = nome senza estensione del file risultato
-- fcoord = funzione di trasformazione coordinate
-- fcolor = funzione di trasformazione colore
local function go(filename, fcoord, fcolor)
   -- memorizzazione comandi
   local t = {}
   for id, dati in pairs(GridS1) do
      local ag = Ag475(dati)
      local lt = Lat(dati)
      local ln = Lon(dati)

      t[#t+1] = string.format(cmask, fcolor(ag))
      t[#t+1] = string.format(dmask, fcoord(ln,lt))
   end

   makecmdfile(filename, t)
end

-- esecuzione
go('defpoint', trasf, wavecolor)

Creare la mappa

Per creare la mappa è sufficiente compilare con pdfLaTeX questo minuscolo file:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{xcolor}
\tikzstyle{every node}=[
    fill,
    minimum size=0.1pt
]

\begin{document}
\begin{tikzpicture}
\input{defpoint}
\end{tikzpicture}
\end{document}

Risultato

La mappa risultato è questa, insieme di 10751 quadratini colorati in modo diverso uno dall’altro (fate un click sull’immagine per scaricarla, un’esperienza da brivido…):

Mappa della pericolosità sismica italiana

La mappa della pericolosità sismica italiana risultato dell’elaborazione descritta nell’articolo

Note tecniche

Per riprodurre la mappa eseguendo il codice mostrato nel post, occorre disporre di una installazione TeX, come TeX Live o MiKTeX, e l’interprete Lua, tutti strumenti gratuiti, o meglio, liberi.
Avremo potuto lavorare con un unico strumento (Lua incorporata in TeX, ovvero LuaTeX, ma lascio il facile esercizio al lettore che non perderà l’occasione di inventarsi nuove scale di colore… 🙂
Alla prossima!

%d blogger hanno fatto clic su Mi Piace per questo: