Costruzione di mappe da dati GIS

Che cosa e' una mappa

Una mappa M e' costituita da tra insiemi di entita' fra loro correlate: P (punti), L (linee), R (regioni) nel piano.
Figura: una mappa.
La regione f2 ha un contorno esterno e due contorni interni.
Il punto p6 e' una feature puntuale di f2.
Le regioni f1 e f5 hanno una feature lineare ciascuna.
Il contorno di f2 e' fatto da cinque linee: p2-p8, p8-p15, p15-p11, p5-p11, p2-p5. La regione f3 e' contornata da due linee aperte, f4 da una linea chiusa.

L'intersezione fra due regioni in una mappa puo' solo essere vuota oppure costituita da linee e/o punti appartenenti alla mappa.
L'intersezione fra due linee in una mappa puo' solo essere vuota oppure costituita da punti estremi comuni alle due linee.
Due punti in una mappa devono essere distinti.
Un punto e una linea in una mappa o sono disgiunti oppure il punto e' un estremo della linea.
L'intersezione fra una regione e un'entita' di dimensione minore (linea o punto) in una mappa puo' solo essere vuota oppure coincidente con l'entita' di dimensione minore.

Descrizione di una mappa

Per descrivere una mappa usiamo una struttura dati che memorizza le seguenti informazioni.

Per ogni vertice v:

Per ogni linea e:

Figura: La linea e ha nell'ordine p1,p2 come punti estremi, e1,e2 come linee associate, f1,f2 come facce associate.

Per ogni regione f:

Operatori per manipolare mappe

Consideriamo operatori costruttivi (aggiungono entita' ad una mappa collegandole a quelle gia' presenti) e distruttivi (eliminano entita' da una mappa).

Operatori costruttivi:

Operatori distruttivi (sono gli inversi dei precedenti):

I dati disponibili

I dati resi disponibili dal Comune di Genova consistono in spezzate poligonali (aperte o chiuse) e punti isolati.

Assumiamo che i dati soddisfino queste proprieta':

Che cosa bisogna fare

Esiste una libreria, chiamata PEG2, che implementa il tipo delle mappe ed una serie di operazioni su mappe tra cui gli operatori costruttivi e distruttivi citati sopra.
La libreria e' implementata sopra CGAL, libreria standard di strutture dati ed algoritmi geometrici.

Bisogna installare e far funzionare CGAL (presupposto per far funzionare PEG2), attualmente l'unica installazione funzionante e' sulla macchina "flash" in Vicolab.

Bisogna scrivere un programma che, presi i dati disponibili, costruisca una mappa. Le operazioni di base per costruirla sono:

e sono implementabili a partire da quelle della libreria PEG2 nel modo seguente.

Inizializzazione della mappa

Creare la faccia infinita: add_infinity_face(f).

Aggiunta di un punto isolato

Localizzare la regione R contenente il punto ed inserire il punto come feature puntuale di R.

Parametri: posizione del nuovo punto, puntatore a un punto che lo conterra'.

procedure add_isolated_point(in: (x,y), out: p)
{
  f := point_location(x,y);
  add_point_feature(f,x,y,p);
}

Supponiamo che la funzione point_location restituisca la regione f contenente la posizione assegnata.
Le istruzioni per implementare questa funzione sono sulle dispense del corso di modellazione geometrica, capitolo 4.
Scegliere il metodo senza pre-elaborazione e usare come algoritmo per controllare se un punto sta in una regione l'algoritmo della semiretta.
Le regioni della mappa possono avere buchi, ma l'algoritmo della semiretta e' comunque valido (bisogna considerare tutti i lati, sia del contorno esterno che dei contorni interni della regione).

Aggiunta di una spezzata aperta

Inserire il primo estremo del primo segmento della spezzata come punto isolato (come descritto sopra). Ricordarsi la regione R in cui e' stato inserito (come conseguenza dell'assunzione che i segmenti non si intersechino, questa regione contiene completamente la spezzata).

Poi, per ogni nuovo segmento della spezzata inserire il secondo estremo come punto isolato ed inserire una feature lineare di R congiungente il punto appena inserito con il precedente.

Parametri: posizioni degli N+1 punti della spezzata, puntatore al primo punto p0 della spezzata che sara' inizializzato, a partire da p0 si potranno recuperare tutte le linee e i punti che compongono la catena (e che saranno stati inizializzati anch'essi).

procedure add_open_chain(in: [(x0,y0),...,(xN,yN)], out: p0)
{
  f := point_location(x0,y0);
  add_point_feature(f,x0,y0,p0);
  p := p0;
  e := null;
  for (i=1...N)
  {  add_point_feature(f,xi,yi,p1);
     add_line_feature(p,p1,e,null,e1);
     p := p1;
     e := e1;
  }
}

Aggiunta di una spezzata chiusa

Procedere nello stesso modo descritto per inserire la spezzata chiusa, senza inserire pero' l'ultimo segmento della spezzata (quello che unisce l'ultimo punto della lista al primo).

L'ultimo segmento (quello che chiude la spezzata) divide la regione f (all'interno della quale e' la spezzata) in due regioni, cioe' ritaglia da f una nuova regione f1.

Parametri: posizioni degli N+1 punti della spezzata, puntatore a una regione f1 che sara' inizializzata con la nuova regione creata all'interno della spezzata, a partire da f1 si potranno recuperare le linee e i punti che formano il suo contorno (e che saranno stati inizializzati anch'essi).

procedure add_closed_chain(in: [(x0,y0),...,(xN,yN)], out: f1)
{
  f := point_location(x0,y0);
  add_point_feature(f,x0,y0,p0);
  p := p0;
  e := null;
  for (i=1...N)
  {  add_point_feature(f,xi,yi,p1);
     add_line_feature(p,p1,e,null,e1);
     if (i==1) e0 = e1;
     p := p1;
     e := e1;
  }
  split_region(f,p0,p1,e1,f1);
}