R kullanarak veriyi lat, lon, value biçiminde bir raster dosyasına nasıl dönüştürebilirim?


40

Kıta ABD’sinde bir km ızgarasının üzerindeki değerler kümesine sahibim. Sütunlar “enlem”, “boylam” ve “gözlem” dir.

"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

veya, bir R veri çerçevesi olarak:

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))

(tam veri seti burada csv olarak indirilebilir )

Veriler, 30 km x 30 km'lik bir ızgaradan (üzerinde olması amaçlanan) bir mahsul modelinden elde edilmiştir ( Miguez ve ark. 2012'den ).

görüntü tanımını buraya girin

Bunları harita projeksiyonu gibi CBS ile ilgili meta verilere sahip bir raster dosyasına nasıl dönüştürebilirim?

İdeal olarak dosya bir metin (ASCII?) Dosyası olacaktır, çünkü platform ve yazılımdan bağımsız olmasını isterdim.


CSV olarak, bu zaten ASCII'de bir "metin dosyası" dır . Ayrıca, hiçbir projeksiyon kullanmadığından, eklenecek çok az ilgili meta veri olabilir (çoğunlukla veri). Ne tür çıktılar aradığınızı ve bununla ne yapmak istediğinizi biraz daha açıklayabilir misiniz?
whuber

Verileri, çeşitli ek haritalama yazılımlarıyla (ArcGIS, Google Haritalar, Grass, R vb.) Kullanabilmek için mümkün olduğunca kolaylaştırmak istiyorum; örneğin, yeniden dönüştürme işlemine gerek duymadan. GIS dosya formatlarının Wikipedia sayfasına dayanarak, 1) inanıyorum ki bir "raster" dosyası, bir resim gibi enlem ve sütun adlarına sahip satır adlarına sahip olmalı ve bu 2) meta verisi coğrafi bilgileri içermelidir (bir köşenin konumu, kaplanan alan verilere göre).
Abe,

Bu, R ve GIS'de karşılaştığım en iyi referanslardan biri. Çok teşekkür ederim! Lütfen doğru proj4string ile birlikte lat ve long ile başka bir csv sağlayabilir misiniz? Bunu gerçekten takdir edeceğim.

@Nandini emin değil doğru proj4string ne, sanıyorum Lambert konformal:proj +proj=lcc +lat_1=50.0 +lat_2=50.0 +units=km +lon_0=-145.5 +lat_0=1.0 . Başka bir csv dosyasıyla ilgili olarak ne sorduğunuzu bilmiyorum - bu soruya iliştirilmiş olandan ne kadar farklı olabilir veya kabul edilen cevap tarafından üretilecekti?
Abe,

benim için çalışmıyor! "X" ve "y" ye ne koyacağımı bilmiyorum "koordinatlar (pts) = ~ x + y"

Yanıtlar:


44

Birkaç adım gerekli:

  1. Bunun normal bir 1km ızgara olduğunu söylüyorsunuz, ancak bu en uzun sürenin normal olmadığı anlamına geliyor. Öncelikle bunu normal bir ızgara koordinat sistemine dönüştürmeniz gerekir, böylece X ve Y değerleri düzenli aralıklarla yerleştirilir.

    a. Veri çerçevesi olarak R'ye, x, y, verim sütunlarıyla okuyun.

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

    b. Sp paketini ve benzeri şeyleri kullanarak veri çerçevesini SpatialPointsDataFrame'e dönüştürün:

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

    c. İlk önce ne CRS olduğunu ve ardından hedefe spTransform'u söyleyerek normal km sisteminize dönüştürün.

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

    d. R'ye bunun ızgaralı olduğunu söyle:

    gridded(pts) = TRUE

    Bu noktada, koordinatlarınız düzenli ve düzenli bir ızgarada yatmıyorsa bir hata alırsınız.

  2. Şimdi bir raster dönüştürmek ve onun CRS ayarlamak için raster paketini kullanın:

    r = raster(pts)
    projection(r) = CRS("insert your proj4 string here")
    
  3. Şimdi bir göz atın:

    plot(r)
  4. Şimdi raster paketini kullanarak bir geoTIFF dosyası olarak yazın:

    writeRaster(r,"pts.tif")

Bu geoTIFF tüm büyük GIS paketlerinde okunabilir olmalıdır. Buradaki açık parça, dönüştürülecek proj4 dizesidir: bu muhtemelen bir tür UTM referans sistemi olacaktır. Daha fazla veri olmadan söylemek zor ...


+1 İş akışını düzenlediğiniz için teşekkür ederiz. Verilerin soruda verilen bağlantıda mevcut olduğuna dikkat edin: bir göz atın. Ne yazık ki, onlar hakkındaki bazı varsayımların yanlış olduğunu keşfedeceksin. (Özellikle, ızgarayı oluşturmak için kullanılan projeksiyonla ilgili herhangi bir belge buldum ama hiçbiri bulamadım. Noktaları çizerek görebileceğiniz gibi tuhaf bir projeksiyon.)
whuber

UTM sistemi olmaya çok yakın, ama denediklerimden hiçbiri R'nin onları izlemesi için normal bir şebekeye yeterince yakın değil. Yarı R nin tüm epsg veri tabanında dolaşmaya başlıyorum ....
Spacedman

İzdüşümü bu şekilde keşfedebilseydin, bu gerçek bir güç olacaktır! Anahtar, bu 7.000+ puanın düzenli bir ızgarada ne kadar yatmaya yeterince yakın olduğunu belirlemek için etkili ve verimli bir kriter bulmaktır (çünkü herhangi bir standart projeksiyonda mükemmel bir ızgara oluşturmayabilirler). Veritabanından hızlı bir şekilde geçmek için, şebekenin kuzey kısmındaki doğu-batı mesafesi gibi az sayıda mesafeyi güneydeki doğu-batı mesafesi ile karşılaştırmanız yeterli olacaktır. Bu, adayların büyük çoğunluğunu hızla ortadan kaldırmalı.
whuber

3
Mathematica 8 tarafından desteklenen tüm (varsayılan) projeksiyonları okudum . Noktaların gerçekte bir ızgaraya düştüğü göründüğü bir izdüşüm buldu: Alaska State Plane (1983) Zone 10! Bu bir Lambert Conformal Conic projeksiyonu. EPSG 26940 olduğuna inanıyorum . Bunu yaklaşık -106 boylamında ortalayacak şekilde değiştirirseniz, noktalar oldukça iyi bir ızgara oluşturur.
whuber

1
Abe, Web sayfasını okumak mı istiyorsun? Öyleydi r = Import[ "https://ebi-forecast.igb.illinois.edu/bety/miscanthusyield.csv", "Data"];. Daha sonra data = Rest[r]; ListPlot[data[[;; , {3, 2}]]](veya ListPointPlot3D[data[[;; , {3, 2, 4}]]]) ile noktaların hızlı bir grafiğini elde edebilirsiniz . Projeler için yardım üzerine başlayın GeoGridPosition, sonra neler olduğunu anlamak için bazı akıllı tahminler ve çapraz referanslar yapın. BTW, @ Spacedman'ın açıklaması gerçekten alakalı: 25 ila 49 derece arasındaki metrik bozulma cos (25) / cos (49) = 1.38; bu önemli.
whuber

29

Sorunun son cevaplanmasından bu yana, rasterFromXYZgerekli tüm adımları (CRS dizesinin belirtilmesi dahil) içeren raster paketin işlevini kullanarak çok daha kolay bir çözüm var .

library(raster)
rasterFromXYZ(mydata)

1
Bana sık sık yardım eden yorulmayan @ Spacedman'dan özür dilerim, ama bence bu cevap neşeli yeşil keneyi almayı hak ediyor.
geotheory

@geotheory Bu cevap, onun büyük bir işlev seçmek olurdu, ancak (op bağlantılı) kullanıyorum veri kümesi üzerinde çok yavaş gibi görünüyor
Abe

1
... aslında boğuldu çünkü ~ 400KB dosyamı aldı ve /tmp/disk alanım bittiğinde ~ 19GB olan bir dosya yarattı .
Abe

Muhtemelen bir yerlerde n-kare bir işlem vardır. Nokta verilerini geniş bir ızgaraya göre gruplandırabilir, her bir grubu ayrı ayrı rasterleştirebilir ve merge()sonuçları birlikte kullanabilirsiniz.
geotheory

Tüm saygımla, ama bu cevap Spacedman’dan çok daha iyi.
Hayalet
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.