Come posso convertire i dati sotto forma di lat, lon, value in un file raster usando R?


40

Ho un set di dati di valori su una griglia di km negli Stati Uniti continentali Le colonne sono "latitudine", "longitudine" e "osservazione", ad esempio:

"lat"    "lon"     "yield"
 25.567  -120.347  3.6 
 25.832  -120.400  2.6
 26.097  -120.454  3.4
 26.363  -120.508  3.1
 26.630  -120.562  4.4

o, come un frame di dati R:

mydata <- structure(list(lat = c(25.567, 25.832, 26.097, 26.363, 26.63), 
lon = c(-120.347, -120.4, -120.454, -120.508, -120.562), 
yield = c(3.6, 2.6, 3.4, 3.1, 4.4)), .Names = c("lat", 
"lon", "yield"), class = "data.frame", row.names = c(NA, -5L))

(il set di dati completo può essere scaricato come CSV qui )

I dati vengono emessi da un modello di coltura (destinato ad essere attivo) su una griglia di 30 km x 30 km (da Miguez et al 2012 ).

inserisci qui la descrizione dell'immagine

Come posso convertirli in un file raster con metadati relativi a GIS come la proiezione delle mappe?

Idealmente il file dovrebbe essere un file di testo (ASCII?) Perché vorrei che fosse indipendente dalla piattaforma e dal software.


Come CSV, questo è già un "file di testo" in ASCII. Inoltre, poiché non utilizza alcuna proiezione, potrebbero essere aggiunti pochi metadati rilevanti (dato, principalmente). Potresti essere un po 'più specifico su quale tipo di output cerchi e cosa intendi fare con esso?
whuber

Vorrei semplificare il più possibile l'utilizzo da parte di qualcuno dei dati con una varietà di software di mappatura (ArcGIS, Google Maps, Grass, R, ecc.) In modo da facilitare il riutilizzo, ad esempio non richiedendo ulteriori passaggi di conversione. Sulla base della pagina Wikipedia dei formati di file GIS, desidero 1) un file "raster" dovrebbe avere rownames con latitudine e nomi di colonna di longitudine, come un'immagine e che 2) i metadati dovrebbero includere informazioni geografiche (posizione di un angolo, area coperta dai dati).
Abe

Questo è uno dei migliori riferimenti che ho trovato su R e GIS. Grazie mille! Potete per favore fornire un altro CSV con lat e long con proj4string corretto? Lo apprezzerò davvero.

@Nandini Non sono sicuro che la proj4string corretta è, ho il sospetto conforme di Lambert:proj +proj=lcc +lat_1=50.0 +lat_2=50.0 +units=km +lon_0=-145.5 +lat_0=1.0 . Non sono sicuro di ciò che stai chiedendo rispetto a un altro file CSV: in che modo differirebbe da quello collegato alla domanda o che sarebbe prodotto dalla risposta accettata?
Abe,

per me non funziona! Non so cosa mettere su "x" e "y" su "coordinate (punti) = ~ x + y"

Risposte:


44

Sono necessari diversi passaggi:

  1. Dici che è una griglia regolare di 1 km, ma ciò significa che i lat-long non sono regolari. Per prima cosa devi trasformarlo in un normale sistema di coordinate della griglia in modo che i valori X e Y siano spaziati regolarmente.

    un. Leggilo in R come un frame di dati, con colonne x, y, yield.

    pts = read.table("file.csv",......)

    b. Converti il ​​frame di dati in SpatialPointsDataFrame usando il pacchetto sp e qualcosa di simile:

    library(sp)
    library(rgdal)
    coordinates(pts)=~x+y

    c. Converti nel tuo sistema di km normale indicandogli prima di che cos'è CRS, quindi spTransform alla destinazione.

    proj4string(pts)=CRS("+init=epsg:4326") # set it to lat-long
    pts = spTransform(pts,CRS("insert your proj4 string here"))

    d. Di 'a R che questo è grigliato:

    gridded(pts) = TRUE

    A questo punto riceverai un errore se le tue coordinate non si trovano su una bella griglia regolare.

  2. Ora usa il pacchetto raster per convertire in raster e impostare il suo CRS:

    r = raster(pts)
    projection(r) = CRS("insert your proj4 string here")
  3. Ora dai un'occhiata:

    plot(r)
  4. Ora scrivilo come file geoTIFF usando il pacchetto raster:

    writeRaster(r,"pts.tif")

Questo geoTIFF dovrebbe essere leggibile in tutti i principali pacchetti GIS. L'ovvio pezzo mancante qui è la stringa proj4 in cui convertire: probabilmente sarà una specie di sistema di riferimento UTM. Difficile dirlo senza ulteriori dati ...


+1 Grazie per aver predisposto il flusso di lavoro. Nota che i dati sono disponibili al link fornito nella domanda: dai un'occhiata. Scoprirai, purtroppo, che alcune delle tue assunzioni al riguardo sono errate. (In particolare, ho cercato qualsiasi documentazione sulla proiezione utilizzata per creare la griglia ma non ne ho trovata nessuna. Ed è una proiezione strana, come puoi vedere tracciando i punti.)
whuber

È molto vicino all'essere un sistema UTM, ma nessuno di quelli che ho provato è abbastanza vicino a una griglia normale per R da grigliarli. Sono quasi tentato di scorrere l'intero database epsg di R ....
Spacedman,

Sarebbe un vero tour de force se potessi scoprire la proiezione in quel modo! La chiave è trovare un criterio efficace ed efficiente per determinare quando questi oltre 7.000 punti sono abbastanza vicini da trovarsi su una griglia regolare (perché è possibile che non formino una griglia perfetta in nessuna proiezione standard). Per una rapida analisi del database, dovrebbe essere sufficiente confrontare un piccolo numero di distanze, come una distanza est-ovest nella parte nord della griglia con una distanza est-ovest nella parte sud. Ciò dovrebbe eliminare rapidamente la stragrande maggioranza dei candidati.
whuber

3
Ho attraversato tutte le proiezioni (predefinite) supportate da Mathematica 8. Ha trovato una proiezione in cui i punti sembrano davvero cadere su una griglia: Alaska State Plane (1983) Zone 10! Questa è una proiezione conica conforme Lambert. Credo che sia EPSG 26940 . Se lo modifichi per centrarlo approssimativamente alla longitudine -106, i punti formano una griglia abbastanza buona.
whuber

1
Abe, intendi leggere la pagina Web? Lo è stato r = Import[ "https://ebi-forecast.igb.illinois.edu/bety/miscanthusyield.csv", "Data"];. Successivamente puoi ottenere un grafico rapido dei punti tramite data = Rest[r]; ListPlot[data[[;; , {3, 2}]]](o ListPointPlot3D[data[[;; , {3, 2, 4}]]]). Per riproiezioni, iniziare con l'aiuto GeoGridPosition, quindi fare alcune ipotesi intelligenti e riferimenti incrociati per capire cosa sta succedendo :-). A proposito, la spiegazione di @ Spacedman è davvero rilevante: la distorsione metrica da 25 a 49 gradi è uguale a cos (25) / cos (49) = 1.38; è sostanziale.
whuber

29

Dall'ultima risposta alla domanda, esiste una soluzione molto più semplice utilizzando la rasterFromXYZfunzione del pacchetto raster che incapsula tutti i passaggi necessari (inclusa la specifica della stringa CRS).

library(raster)
rasterFromXYZ(mydata)

1
Mi scuso con l'instancabile @Spacedman, che mi ha aiutato spesso, ma penso che questa risposta meriti di ereditare il segno di spunta verde allegro.
geotheory,

@geotheory Sceglierei questa risposta, è un'ottima funzione, ma sembra essere molto lento sul set di dati che sto usando (collegato all'operazione)
Abe

1
... in effetti è soffocato perché ha preso il mio file ~ 400 KB e creato un file /tmp/che era ~ 19 GB quando ho esaurito lo spazio su disco.
Abe,

C'è probabilmente un processo n-quadrato da qualche parte. Potresti essere in grado di raggruppare i dati dei punti in una griglia ampia, rasterizzare ogni gruppo singolarmente e quindi merge()i risultati insieme.
geotheory,

Con tutto il dovuto rispetto, ma questa risposta è decisamente migliore di quella di Spacedman.
Ghost
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.