Si implementa la classe HwndArco che permette di compiere operazioni di spostamento, divisione e rimozione degli archi della rete stradale. Nella fase iniziale di avvio, la componente Display dell’editor crea un’istanza della classe, che si pone in uno stato di attesa HAWAIT. La chiamata di callback setAzione avvia i servizi interattivi, che abilitano i seguenti metodi:
• azionaEvento, si attiva con un click del mouse;
• trascinaEvento, si attiva con il tasto sinistro del mouse premuto, per spostare un elemento nella scena grafica;
• fineEvento, si attiva con il rilascio del tasto del mouse, dopo la fase di trascinamento;
• testSelezione, si attiva con il semplice movimento del mouse; • disegnaStato, si attiva quando si ridisegna la scena.
In base allo stato corrente della classe detti metodi possono eseguire diverse operazioni.
Spostamento degli archi
Il metodo initSpostamento pone lo stato della classe su HASPOSTAINIT, che attiva il servizio per permettere lo spostamento interattivo di un nodo u. Il metodo testSelezione determina il nodo u∗ (interno ui o estremo ue)
pi`u vicino al punto di selezione del mouse. Con un clik del tasto sinistro del mouse su u∗ si attiva la funzione azionaEvento, che se:
• u∗ = ue, ricava le coordinate di ue;
• u∗ = ui, determina il cursore p della polilinea che contiene uie l’id punto
di ui.
Gli archi cos`ı individuati vengono memorizzati in un vettore di appog- gio v. Con il tasto sinistro premuto e trascinando il puntatore, si attiva il metodo trascinaEvento, che consente di spostare u∗ e gli archi ad esso con-
nessi nella scena grafica. Questo utilizza la funzione getcoordinatebymouse per convertire le coordinate di tipo finestra del mouse in quelle Pm di tipo
mondo. Se u∗ = ui, allora per definizione gli archi da spostare sono due
(cap. 1.2). Il metodo, poi, attiva la funzione getpolyref(p), che restituisce il cursore a0 del primo arco della polilinea p. Essendo la struttura dei cursori
un’enumerazione crescente, allora ui connette gli archi ax = a0+ id punto − 1
e ax+1 = a0 + id punto. Lo spostamento diui si concretizza assegnando la
coordinata Pf al nodo di coda di ax e a quello di testa di ax+1. Se invece
u∗ = ue, allora gli archi connessi a ue possono essere un numero variabile
maggiore o uguale di uno. In questo caso trascinaEvento ricava la lista dei cursori {p0, p1, . . . , ph−1} delle polilinee connesse a ue. Per ogni pi determina
il cursore a0 del primo arco di pi e il numero k di archi che compongono pi.
Ricava, anche, l’arco ai collegato a ue e modifica le sue coordinate sfruttando
le propriet`a dei cursori:
• se pi < 0, allora pone a = a0 e assegna al nodo di testa di a le coordinate
Pm;
• se pi > 0, allora pone a = a0+ k − 1 e assegna al nodo di coda di a le
coordinate Pm.
Essendo ue un nodo estremo dotato di proprie coordinate, trascinaEven-
to pone ue = Pf. Una volta rilasciato il tasto del mouse si attiva il metodo
fineEvento, che ratifica l’azione di spostamento di u∗ con il conseguente po-
sizionamento degli archi interessati. Questo avvia la funzione rimuovilinea sugli archi, che cancella gli archi da modificare per, poi, reinserli con le nuove
modifiche apportate. Ci`o consente al sistema di mantenere sempre sincro- nizzata la griglia al grafo. Stessa opera di aggiornamento viene effettuata sulle coordinate geografiche degli elementi di Vp e Vn, per renderle coerenti
con quelle degli archi modificati. Con la chiamata di callback setAzione in- fine si attiva il metodo fineSpostamento, che resetta lo stato della classe su HAWAIT.
Divisione degli archi
Il metodo initSplit pone lo stato della classe su HASPLITINIT, che attiva il servizio per permettere la divisione di un arco a = (u, v) in corrispondenza di un punto w interno ad a. Il metodo testSelezione attiva la funzione distan- zaarcoclick, che restituisce il cursore dell’arco a vicino al punto selezionato dal mouse. Con un click del mouse, in corrispondenza di a, si avvia la funzione azionaEvento, che memorizza a e setta lo stato della classe su HASPLITSE- PARA. Alla pressione del tasto sinistro del mouse si riattiva nuovamente il metodo azionaEvento, che determina le coordinate del punto p selezionato dal mouse. Con il tasto sinistro premuto e trascinando il puntatore si avvia il metodo trascinaEvento, che calcola le coordinate del punto q selezionato dal mouse. La chiamata di callback disegna la scena grafica mediante la funzione disegnaStato, che inserisce il segmento formato dai nodi (p, q). La procedura si ripete fino al rilascio dell tasto del mouse, che richiama il metodo fineE- vento. Questo calcola il punto di intersezione tra a e (p, q), che determina il punto w interno a a, per dividere l’arco in due sottoarchi (u, w) e (w, v) (figura 2.10).
Figura 2.10: Divisione di un arco
La chiamata di callback setAzione attiva il metodo salvaSplit, che so- stituisce la polilinea P = {p0, p1, . . . , u, v, . . . , ph−1} di a con una nuova
P0 = {p0, p1, . . . , u, w, v, . . . , ph}. Aggiorna le strutture dati griglia Vp e Vn
con i metodi rimuovipoli(P ) e inspoly(P0). La divisione di a o l’annullamento della procedura determinano l’attivazione della funzione fineSplit, che resetta lo stato della classe su HAWAIT.
Rimozione degli archi
Il metodo initRimuovi pone lo stato della classe su HADELINIT, che attiva il servizio per permettere la cancellazione di un arco a = (u, v). Il metodo testSelezione avvia la funzione distanzaarcoclick, che restituisce il cursore dell’arco a vicino al punto selezionato dal mouse. Con un click in corrispondenza di a si attiva la funzione azionaEvento che memorizza a. La chiamata di callback setAzione attiva il metodo salvaRimuovi, che sostituisce la polilinea P = {p0, p1, . . . , pi, u, v, pj, . . . , ph−1} di a con una nuova P0 =
{p0, p1, . . . , pi, pj, . . . , ph−1} e aggiorna le strutture dati Griglia, Vp e Vn con i
metodi rimuovipoli(P ) e inspoly(P0). La cancellazione di a o l’annullamento della procedura determinano l’attivazione della funzione fineRimuovi, che resetta lo stato della classe su HAWAIT.