---
disqus: ahb0222
GA : G-CQ4L16KHK4
---
# R語言讀取TIF檔並轉成csv檔
> [color=#40f1ef][name=LHB阿好伯, 2021/10/23][:earth_africa:](https://www.facebook.com/LHB0222/)
###### tags: `R`
[TOC]

今天來分享一個最近做的小東西
TIF(Tagged-Image File Format)檔是常見的一種點陣圖檔
常應用在像是地形圖
在特定時候可能會需要它的原始數據
嘗試了幾個方法後成功轉成CSV檔
# 快速使用方法
## 安裝R
https://cran.r-project.org/bin/windows/base/


# 資料來源
[內政部20公尺網格數值地形模型資料](https://data.gov.tw/dataset/35430)
# Shiny App
將下面程式碼貼到R Console中即可

第一次執行可能會花比較多時間安裝套件
第二次就會比較快了

第一次須執行一次
```r=
install.packages("pacman")
```
```r=+
library(pacman)
p_load("rgdal", "raster", "Rcpp", "sp", "flexdashboard", "shiny","waiter","data.table")
#首先檢查當前的內存限制
memory.limit()
#重新設置內存限制
memory.limit(1000000)
ui <- fluidPage(
# Application title
titlePanel("TIF to CSV"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
autoWaiter(),
fileInput("file1", "請選擇TIF檔", accept = c(".tiff", "tif")),
textInput("outfillname", "輸出檔名",value = "output"),
submitButton( "轉檔", icon = icon("list") ),
textOutput("file2"),
textOutput("runtime")
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
options(shiny.maxRequestSize=1000*1024^2)
#file <- input$file1
output$distPlot <- renderPlot({
TIFfill <- input$file1$datapath
grey <- raster(TIFfill)
plot(grey)
t1=proc.time()
fwrite(as.data.frame(grey, xy = T),file = paste0(input$outfillname,".csv"))
t2=proc.time()
t3=t2-t1
output$file2 <- renderText(paste0("輸出位置 : ",getwd(),"/"))
output$runtime <- renderText(print(paste0('執行時間:',t3[3][[1]],'秒')))
})
}
# Run the application
shinyApp(ui = ui, server = server)
```
執行成功後就會出現以下畫面

測試過 tiff、rgdal、raster 套件
最後使用raster套件成功轉出資料
```r=
install.packages("pacman")
library(pacman)
p_load("rgdal", "raster", "Rcpp", "sp", "flexdashboard")
TIFfill <- file.choose()
grey <- raster(TIFfill)
str(grey)
View(grey)
plot(grey)
```

# 轉檔輸出
使用as.data.frame就可以得到相關的數據
```r=
View(as.data.frame(grey, xy = T))
```
## 內存限制
在這過程中可能會遇到內存不夠的問題
可以使用下面的函數修改
```r=
#首先檢查當前的內存限制
memory.limit()
#重新設置內存限制
memory.limit(1000000)
```
# 輸出csv
若是想直接在Rstudio輸出數據可能會出現
整個電腦當掉的問題
最好的方式還是直接輸出成csv檔
```r=
fwrite(as.data.frame(grey, xy = T),file = "tif.csv")
```
最後在轉檔的過程發現一件很恐怖的事情
最後的檔案大小會相差近15倍
5,933,840,209/389,238,784 (位元) =15.2
若是沒必要就不要亂轉檔XD
# tkinter GUI設計
後續利用R內建的tkinter我設計了一個可以擷取所需範圍的功能

```r=
{library(pacman)
p_load("rgdal", "raster", "Rcpp", "sp", "flexdashboard","rmarkdown","tcltk","data.table")
#首先檢查當前的內存限制
memory.limit()
#重新設置內存限制
memory.limit(1000000)
TIFplot <<- NA
TIFfill <<- NA
tt <- tktoplevel()
label.widget <- tklabel(tt, text = "TIFF2CSV")
button.widget1 <- tkbutton(tt, text = "畫圖",
command = function(){
t1=proc.time()
TIFfill <<- file.choose()
TIFplot <<- raster(TIFfill)
plot( TIFplot )
t2=proc.time()
t3=t2-t1
print(paste0('執行完成耗時:',t3[3][[1]],'秒'))
})
button.widget2 <- tkbutton(tt, text = "截圖",
command =function(){
t1=proc.time()
crop_range <<- extent(locator(2))
TIFplot2 <<- raster::crop(TIFplot,crop_range)
plot(TIFplot2)
t2=proc.time()
t3=t2-t1
print(paste0('執行完成耗時:',t3[3][[1]],'秒'))
})
#entry1 <- tkentry(tt, text = "輸出檔名")
button.widget3 <- tkbutton(tt, text = "截圖輸出",
command =function(){
t1=proc.time()
fwrite(as.data.frame(TIFplot2, xy = T),file = "tif.csv")
df <- data.table::fread("tif.csv")
colnames(df) <- c("utme(m)", "utmn(m)", "alt(m)")
df$`utme(m)` <- df$`utme(m)`/1000
df$`utmn(m)` <- df$`utmn(m)`/1000
fwrite(df,file = "terrain.asc",sep = "\t")
t2=proc.time()
t3=t2-t1
print(paste0('執行完成耗時:',t3[3][[1]],'秒'))
})
button.widget4 <- tkbutton(tt, text = "未截圖輸出",
command =function(){
t1=proc.time()
fwrite(as.data.frame(TIFplot, xy = T),file = "tif1.csv")
df <- data.table::fread("tif1.csv")
colnames(df) <- c("utme(m)", "utmn(m)", "alt(m)")
df$`utme(m)` <- df$`utme(m)`/1000
df$`utmn(m)` <- df$`utmn(m)`/1000
fwrite(df,file = "terrain.asc",sep = "\t")
t2=proc.time()
t3=t2-t1
print(paste0('執行完成耗時:',t3[3][[1]],'秒'))
})
entry1 <- tkentry(tt, textvariable=filename)
# 輸出 tkentry()資料
button.widget5 <- tkbutton(tt, text = "輸出",
command =function(){
print(tclvalue(filename))})
tkpack(label.widget, button.widget1, entry1, button.widget2, button.widget3, button.widget4, button.widget5 ) # 執行GUI
}
```
🌟全文可以至下方連結觀看或是補充
全文分享至
https://www.facebook.com/LHB0222/
https://www.instagram.com/ahb0222/
有疑問想討論的都歡迎於下方留言
喜歡的幫我分享給所有的朋友 \o/
有所錯誤歡迎指教
# [:page_with_curl: 全部文章列表](https://hackmd.io/@LHB-0222/AllWritings)
