Как я могу преобразовать данные в форме широты, долготы, значения в растровый файл, используя R?

40

У меня есть набор данных по сетке километров в континентальной части США. Столбцы «широта», «долгота» и «наблюдение», например:

"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

или, как фрейм данных 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))

(полный набор данных можно скачать как CSV здесь )

Данные выводятся из модели культуры (предназначенной для включения) в сетку 30 км х 30 км (из Miguez et al 2012 ).

введите описание изображения здесь

Как я могу преобразовать их в растровый файл с метаданными, связанными с ГИС, такими как проекция карты?

В идеале файл должен быть текстовым (ASCII?), Потому что я хотел бы, чтобы он был независимым от платформы и программного обеспечения.

Abe
источник
Как CSV, это уже является «текстовым файлом» в ASCII. Кроме того, поскольку он вообще не использует проекцию, может быть мало релевантных метаданных для добавления (в основном, данных). Не могли бы вы немного конкретнее рассказать о том, какой выход вы ищете и что вы собираетесь с ним делать?
whuber
Я бы хотел, чтобы кто-то как можно проще использовал данные для различных картографических программ (ArcGIS, Google Maps, Grass, R и т. Д.), Чтобы облегчить их повторное использование, например, не требуя дополнительных шагов преобразования. Основываясь на странице Википедии о форматах файлов ГИС, я делаю вывод, что 1) «растровый» файл должен иметь имена строк с широтой и имена столбцов долготы, например изображение, и 2) метаданные должны включать географическую информацию (расположение угла, покрываемая область по данным).
Abe
Это одна из лучших ссылок, с которыми я сталкивался на R и GIS. Большое спасибо! Можете ли вы предоставить другой CSV с Lat и Long с правильным Proj4string? Я действительно ценю это.
@Nandini Не уверен, что правильная строка proj4string, я подозреваю, что Ламберт конформныйproj +proj=lcc +lat_1=50.0 +lat_2=50.0 +units=km +lon_0=-145.5 +lat_0=1.0 . Я не уверен, что вы запрашиваете в отношении другого CSV-файла - как он будет отличаться от того, на который ссылается вопрос, или что будет получено в результате принятого ответа?
Абэ
для меня не работает! Я не знаю, что поставить "x" и "y" в "координаты (pts) = ~ x + y"

Ответы:

44

Требуется несколько шагов:

  1. Вы говорите, что это обычная 1-километровая сетка, но это означает, что широта не является регулярной. Сначала вам нужно преобразовать его в регулярную систему координат сетки, чтобы значения X и Y регулярно располагались.

    а. Прочитайте его в R как фрейм данных со столбцами x, y, yield.

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

    б. Преобразуйте фрейм данных в SpatialPointsDataFrame, используя пакет sp и что-то вроде:

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

    с. Преобразуйте в свою обычную систему km, сначала сообщив ей, что это за CRS, а затем spTransform до места назначения.

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

    д. Скажите R, что это сетка:

    gridded(pts) = TRUE

    В этот момент вы получите ошибку, если ваши координаты не лежат на хорошей регулярной сетке.

  2. Теперь используйте растровый пакет для преобразования в растр и установите его CRS:

    r = raster(pts)
    projection(r) = CRS("insert your proj4 string here")
  3. Теперь посмотрим:

    plot(r)
  4. Теперь запишите его как файл geoTIFF, используя растровый пакет:

    writeRaster(r,"pts.tif")

Этот geoTIFF должен быть доступен для чтения во всех основных пакетах ГИС. Очевидным недостающим фрагментом здесь является строка proj4 для преобразования: это, вероятно, будет какая-то система ссылок UTM. Трудно сказать без каких-либо дополнительных данных ...

Spacedman
источник
+1 Спасибо за выкладывание рабочего процесса. Обратите внимание, что данные доступны по ссылке, указанной в вопросе: посмотрите. Увы, вы обнаружите, что некоторые ваши предположения о них неверны. (В частности, я искал любую документацию о проекции, использованной для создания сетки, но не нашел ни одной. И это странная проекция, как вы можете увидеть,
нанося
Она очень близка к системе UTM, но ни одна из тех, что я пробовал, не достаточно близка к обычной сетке, чтобы R мог их объединить. Я наполовину испытывал желание пройтись по всей базе данных epsg R ...
Spacedman
Это было бы настоящим путешествием, если бы вы могли открыть проекцию таким образом! Ключ заключается в том, чтобы найти эффективный и действенный критерий, чтобы определить, когда эти 7 000+ точек достаточно близки к тому, чтобы лежать на регулярной сетке (потому что возможно, что они вообще могут не образовывать идеальную сетку в любой стандартной проекции). Для быстрого просмотра базы данных достаточно сравнить небольшое количество расстояний, например, расстояние восток-запад в северной части сетки, и расстояние восток-запад в южной части. Это должно быстро устранить подавляющее большинство кандидатов.
whuber
3
Я пробежал все (по умолчанию) проекции, поддерживаемые Mathematica 8. Он нашел проекцию, в которой точки действительно падают на сетку: Аляска, штатная плоскость (1983), зона 10! Это конформная коническая проекция Ламберта. Я считаю, что это EPSG 26940 . Если вы измените это, чтобы центрировать его приблизительно на -106 долготы, точки образуют довольно хорошую сетку.
whuber
1
Эйб, ты хочешь прочитать веб-страницу? Это было r = Import[ "https://ebi-forecast.igb.illinois.edu/bety/miscanthusyield.csv", "Data"];. Вы можете получить быстрый график точек затем через data = Rest[r]; ListPlot[data[[;; , {3, 2}]]](или ListPointPlot3D[data[[;; , {3, 2, 4}]]]). Для репроекций, начните с помощи GeoGridPosition, затем сделайте некоторые умные предположения и перекрестные ссылки, чтобы выяснить, что происходит :-). Кстати, объяснение @ Spacedman действительно актуально: метрическое искажение от 25 до 49 градусов равно cos (25) / cos (49) = 1,38; это существенно.
whuber
29

Поскольку вопрос был последний ответил, гораздо проще решение существует с помощью растра ПАКЕТ в rasterFromXYZфункцию , которая инкапсулирует все шаги , необходимые (включая спецификацию строки CRS).

library(raster)
rasterFromXYZ(mydata)
Лукас Фортини
источник
1
Извиняюсь перед неутомимым @Spacedman, который часто помогал мне, но я думаю, что этот ответ заслуживает того, чтобы унаследовать веселую зеленую галочку.
геотеория
@geotheory Я бы выбрал этот ответ, его отличная функция, но он кажется очень медленным в наборе данных, который я использую (ссылка на него в статье)
Abe
1
... на самом деле он задохнулся, потому что он взял мой файл ~ 400 КБ и создал файл размером ~ 19 /tmp/ГБ, когда мне не хватило места на диске.
Абэ
Там, вероятно, где-то есть процесс с квадратом n. Возможно, вы сможете сгруппировать данные точек по широкой сетке, растеризовать каждую группу отдельно, а затем merge()результаты вместе.
геоэтерия
При всем уважении, но этот ответ намного лучше, чем у Spacedman.
Призрак