2010-11-13 11 views
6

Ho una mappa che ho convertito da un grafico raster in un file SVG convertendo le aree diversamente colorate in tracciati.Punto in poligono controlla con SVG e JavaScript?

so come fare un controllo di base punto-a-poligono dato un array di spigoli, ma gli svg:path elementi rappresentano più poligoni e maschere (per tenere conto mari ecc) e l'estrazione di tali informazioni analizzando l'attributo d sembra piuttosto pesante.

C'è una libreria JS che mi consente di semplificare tale controllo? Fondamentalmente voglio creare punti casuali e quindi verificare se sono a terra (cioè all'interno dei poligoni) o acqua (cioè all'esterno).

Dato che gli elementi SVG sembrano consentire la gestione degli eventi del mouse, ritengo che questo non dovrebbe essere un grosso problema (ad esempio, se si può stabilire se il puntatore del mouse si trova sopra un elemento, si sta già risolvendo il problema problema point-in-poligono).

EDIT: A complicare la questione un po ', devo dire che gli elementi svg:path sembrano essere basate su curve anziché linee, quindi basta parsing l'attributo d per creare una matrice di bordi non sembra essere un'opzione.

Poiché gli elementi possono assumere un attributo fill, un approccio ghetto di rendering dell'SVG su una tela e quindi di trovare il valore del colore del pixel nel punto specificato potrebbe funzionare, ma sembra un modo davvero, davvero terribile di fallo.

+0

Dopo aver lavorato con le specifiche SVG e aver trascorso un'ora con la console JavaScript di Chrome, sembra che il problema più grande sia che ho un elemento 'svg: percorso' piuttosto che un elemento forma regolare. Altrimenti potrebbe essere possibile usare 'svg.checkIntersection' con 1x1' svg: rect' (supponendo che funzioni per le aree piuttosto che per i contorni). L'API SVG sembra essere di scarso aiuto se stai cercando qualsiasi forma di astrazione. –

risposta

3

Le risposte su Hit-testing SVG shapes? possono aiutarti in questa ricerca. Ci sono problemi con il supporto del browser mancante, ma potresti forse usare svgroot.checkIntersection per eseguire il test di un rettangolo piccolo (forse anche di larghezza/altezza 0 funzionerebbe?) All'interno della forma del poligono.

1

L'approccio che ho suggerito come ultima risorsa sembra essere la soluzione più semplice per questo problema.

Ho trovato a nice JS library che semplifica il rendering di SVG su una tela. Con SVG renderizzato, basta una chiamata al metodo getImageData del contesto 2D per un'area 1x1 nel punto che si desidera controllare. Immagino che aiuti a creare una copia dell'SVG con la codifica a colori per rendere più semplice il controllo se il tuo SVG è più complesso di quello che sto usando (dovrai controllare il valore RGBA byte per byte).

Questo sembra terribilmente fastidioso mentre in realtà stai ispezionando i pixel di un'immagine raster, ma le prestazioni sembrano essere abbastanza decenti e le verifiche dei colori possono essere scritte in un modo che consenta le impurità (ad esempio vicino ai bordi).

Suppongo che se si desiderano le coordinate relative, è possibile provare a creare una tela di dimensioni 1-a-1 e quindi dividere le coordinate dei pixel in base alle dimensioni della tela.

Se qualcuno ha una risposta migliore, lo accetto invece. Fino ad allora, questo serve da segnaposto nel caso qualcuno venga qui con lo stesso problema alla ricerca di una soluzione facile.

+0

Se stai cercando di individuare il clic di un utente, i pathnode svg attivano quell'evento. Inoltre, getImageData non è emulato da iecanvas, mi sono imbattuto in quel problema. –