Skip to content

Commit 250fc68

Browse files
unknownunknown
authored andcommitted
changes
1 parent c493810 commit 250fc68

11 files changed

Lines changed: 85 additions & 34 deletions

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
^.*\.Rproj$
22
^\.Rproj\.user$
3+
^\.travis\.yml$

.travis.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Sample .travis.yml for R projects
2+
3+
language: r
4+
warnings_are_errors: true
5+
sudo: required
6+
7+
env:
8+
global:
9+
- CRAN: http://cran.rstudio.com
10+
11+
notifications:
12+
email:
13+
on_success: change
14+
on_failure: change

DESCRIPTION

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1+
Type: Package
12
Package: MSScvm
23
Title: Automated Cloud Masking for Landsat MSS Images
34
Version: 1.0.0
45
Date: 2015-07-23
56
Authors@R: c(person("Justin", "Braaten", email = "jstnbraaten@gmail.com", role = c("aut", "cre")),
67
person("Warren", "Cohen", email = "warren.cohen@oregonstate.edu", role = "aut"),
78
person("Zhiqiang", "Yang", email = "zhiqiang.yang@oregonstate.edu", role = "aut"))
8-
Description: An automated cloud and cloud shadow masking system for Landsat MSS imagery. It allows MSS imagery to more easily be used in large-area and time series analysis by providing an efficent way to prevent cloud and cloud shadow pixels from contaminating mosaics, composites, and time series.
9+
Description: An automated cloud and cloud shadow masking system for Landsat MSS imagery. It provides a means of more easily incorporating MSS imagery in large-area and time series analysis by providing an efficient way to prevent cloud and cloud shadow pixels from contaminating mosaics, composites, and time series.
910
Depends: R (>= 3.2.1)
1011
Imports:
1112
gdalUtils,
1213
igraph,
1314
raster,
1415
rgdal,
1516
SDMTools
17+
SystemRequirements: GDAL binaries
1618
License: GPL-2
19+
URL: http://www.msscvm.jdbcode.com/
1720
LazyData: true

R/MSScvm.r

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717

1818
MSScvm = function(imgDir, demFile, classify=F){
19-
19+
20+
21+
2022
#get the image file and check
2123
files = list.files(imgDir, full.names=T)
2224
refl_match = grep("toa_reflectance.tif$", files)
@@ -36,12 +38,22 @@ MSScvm = function(imgDir, demFile, classify=F){
3638
}
3739

3840
imgfile = files[match]
41+
print(paste("Making cloud & shadow mask for",basename(imgfile)))
3942

4043
#get some info about the image
4144
ref = raster::raster(imgfile) #read in the MSS file for information on image extent and as a template for holding values later
4245
dem = raster::raster(demFile) #read in the DEM file - raster package function
4346
demproj = raster::projection(dem)
4447
imgproj = raster::projection(ref)
48+
demres = raster::xres(dem)
49+
imgres = raster::xres(ref)
50+
51+
#check to make the DEM and image resolutions are the same
52+
if(demres != imgres){
53+
print(paste("The DEM file:",demFile,"does not have the same pixel resolution as the image file."))
54+
print("Please make sure the DEM file has the same pixel resolution as the image file. Use the function 'reprojectDEM' to assist in getting it in the same resolution")
55+
stop("Stopping MSScvm")
56+
}
4557

4658
#check to make the DEM and image projections are the same
4759
if(demproj != imgproj){
@@ -99,13 +111,15 @@ MSScvm = function(imgDir, demFile, classify=F){
99111
b4 = refl(imgfile, 4 ,info$b4gain, info$b4bias, sunzen, d, esun[4]) #get TOA reflectance for MSS band 4
100112
}
101113

114+
102115
if(imgtype == "refl") {
103116
#load in the image bands
104117
b1 = raster::as.matrix(raster::raster(imgfile, 1)) #band 1
105118
b2 = raster::as.matrix(raster::raster(imgfile, 2)) #band 2
106119
b4 = raster::as.matrix(raster::raster(imgfile, 4)) #band 4
107120
}
108121

122+
109123
#crop the hillshade layer
110124
dem_ex = raster::alignExtent(dem, ref, snap="near") #aligned the extent of the DEM to the image - raster package function
111125
raster::extent(dem) = dem_ex #set the DEM extend to aligned extent - raster package function

R/MSSdn2rad.r

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515

1616
MSSdn2rad = function(imgFile){
1717

18+
print(paste("Converting",basename(imgFile),"to TOA radiance"))
1819
info = getMetadata(imgFile) #get image metadata
1920
b = raster::brick(imgFile) #load the DN image as a brick
20-
img = as.array(b) #convert the brick to an array
21+
img = raster::as.array(b) #convert the brick to an array
2122

2223
img[,,1] = round(100*((info$b1gain*img[,,1])+info$b1bias)) #convert fro DN to radiance and scale by 100 and round
2324
img[,,2] = round(100*((info$b2gain*img[,,2])+info$b2bias)) #convert fro DN to radiance and scale by 100 and round

R/MSSdn2refl.r

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717

1818
MSSdn2refl = function(imgFile){
1919

20+
print(paste("Converting",basename(imgFile),"to TOA reflectance"))
2021
#link to the equations to convert DN to TOA and TOA to SR
2122
#http://landsathandbook.gsfc.nasa.gov/data_prod/prog_sect11_3.html
2223

2324
#define the TOA reflectance function
2425
refl = function(imgFile, band, gain, bias, sunzen, d, esun){
2526
orig = raster::raster(imgFile, band) #read in the file
26-
img = as.matrix(orig) #convert from raster to matrix
27+
img = raster::as.matrix(orig) #convert from raster to matrix
2728
img = ((gain*img)+bias) #convert from DN to TOA radiance
2829
img[img < 0] = 0 #set all values less than 0 to 0 - negative radiance does not make sense
2930
img = (pi * img * (d^2))/(esun * cos(sunzen)) #convert from TOA radiance to TOA reflectance

R/MSSunpack.r

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
MSSunpack = function(imgFile, toaRad=FALSE, toaRefl=FALSE, useL1G=FALSE){
2727

2828
#figure out if this is an L1G image and stop the function according to the 'useL1G' parameter
29+
print(paste("Unpacking and preparing",basename(imgFile)))
2930
tempdir = file.path(dirname(imgFile),"temp")
3031
untar(imgFile, exdir=tempdir)
31-
if(useL1G == F){
32-
mtlfile = list.files(tempdir, pattern = "MTL.txt", full.names = T, recursive = T) #find the mtl metadata file
33-
info = getMetadata(mtlfile)
34-
if(info$datatype == "L1G"){
32+
mtlfile = list.files(tempdir, pattern = "MTL.txt", full.names = T, recursive = T) #find the mtl metadata file
33+
info = getMetadata(mtlfile)
34+
if(useL1G == F & info$datatype == "L1G"){
35+
unlink(tempdir, recursive=T, force=T) #delete the temp folder and its contents
3536
print(paste("MSS file:",imgFile,"is L1G, if you want to use it, set the 'useL1G' parameter to TRUE"))
3637
stop("Stopping MSSunpack")
37-
}
3838
}
3939

4040
#get file and directory info
@@ -54,8 +54,8 @@ MSSunpack = function(imgFile, toaRad=FALSE, toaRefl=FALSE, useL1G=FALSE){
5454
newancfiles = file.path(outdir, baseancfiles) #define the new filenames for ancillary files
5555

5656
#start working with the image files - stack and set bad pixels to 0
57-
s = stack(tiffiles[1],tiffiles[2],tiffiles[3],tiffiles[4]) #stack the band files
58-
img = as.array(s) #convert to array for fastering processing
57+
s = raster::stack(tiffiles[1],tiffiles[2],tiffiles[3],tiffiles[4]) #stack the band files
58+
img = raster::as.array(s) #convert to array for fastering processing
5959
b1bads = img[,,1]>1 #finds bad image edge pixels that cause problems when mosaicing
6060
b2bads = img[,,2]>1 #finds bad image edge pixels that cause problems when mosaicing
6161
b3bads = img[,,3]>1 #finds bad image edge pixels that cause problems when mosaicing

R/mosaicDEMs.r

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
#' A helper function to create the large-extent DEM file required by the 'MSScvm' function.
44
#' @param dir directory name (character). Full path to a directory containing digital elevation model (DEM) files to be mosaiced.
55
#' @param projRef filename (character). Full path to an image file produced by the \code{\link{MSSunpack}} function.
6-
#' @param NAvalue numeric. What is the background value of the DEM files in the directory.
6+
#' @param srcNodata numeric. What is the background value of the DEM files in the directory. If there is no background value, use NA (default)
7+
#' @param dstNodata numeric. Specify the value to represent background pixels in the mosaic DEM. -32768 is the default
78
#' @details The provided directory path should only contain decompressed digital elevation files from the same source (SRTM, NED, GTOPO, etc).
89
#' The function will search the directory and include all files found in the mosaic. It is important that each file have the same background value
9-
#' and that it is correctly assigned to the 'NAvalue' parameter, if not, intersection between DEMs could have unexpected results.
10+
#' and that it is correctly assigned to the 'srcNodata' parameter, if not, intersection between DEMs could have unexpected results.
1011
#' Each individual DEM file will be adjusted to match the projection and pixel resolution of the 'proRef' image.
1112
#' Then they will be merged using the mean value of intersecting pixels.
1213
#' @return A GeoTIFF raster file representing the union of all individual DEM files found in the provided directory path. The mosaic file will be written to the
@@ -16,12 +17,12 @@
1617
#'
1718
#' mosaicDEMs(dir = "C:/mss/dems",
1819
#' projRef = "C:/mss/LM10360321973191AAA04/LM10360321973191AAA04_dn.tif",
19-
#' NAvalue = -32768)
20+
#' srcNodata = -9999, dstNodata= -32768)
2021
#' }
2122
#' @export
2223

2324

24-
mosaicDEMs = function(dir, projRef, NAvalue){
25+
mosaicDEMs = function(dir, projRef, srcNodata=NA, dstNodata=-32768){
2526

2627
align = function(img, refimg){
2728
img = raster::raster(img)
@@ -35,16 +36,26 @@ mosaicDEMs = function(dir, projRef, NAvalue){
3536
proj = raster::projection(template)
3637
demfiles = normalizePath(list.files(dir, full.names=T))
3738

39+
#check files to see if they are compressed
40+
zip = grep("zip", demfiles)
41+
tar = grep("tar", demfiles)
42+
gz = grep("gz", demfiles)
43+
if(sum(length(zip),length(tar),length(gz)) != 0){
44+
print(paste("There are compressed files in this directory:",dir))
45+
print("make sure the directory only contains decompressed files")
46+
stop("Stopping mosaicDEMs")
47+
}
48+
3849
for(i in 1:length(demfiles)){
3950
demfile = demfiles[i]
40-
print(paste("Reprojecting file:",demfile))
51+
print(paste("Reprojecting",basename(demfile)))
4152
bname = basename(demfile)
4253
extension = substr(bname,(nchar(bname)-3),nchar(bname))
4354
dstfile = sub(extension, "_reprojected.tif", demfile)
4455

4556
gdalUtils::gdalwarp(srcfile=demfile, dstfile=dstfile,
46-
t_srs=proj, of="GTiff",
47-
r="near", dstnodata=NAvalue, multi=T,
57+
t_srs=proj, of="GTiff", overwrite=TRUE,
58+
r="near", srcnodata=srcNodata, dstnodata=dstNodata, multi=T,
4859
tr=c(reso,reso), co="INTERLEAVE=BAND")
4960
}
5061

@@ -58,21 +69,17 @@ mosaicDEMs = function(dir, projRef, NAvalue){
5869

5970
refimg = raster::raster(demfiles[1])
6071

72+
outfile = file.path(dir,"dem_mosaic.tif")
6173
big = NA #create a dummy variable to be overwritten on-the-fly with eval
6274
for(i in 1:len){
6375
if(i == 1){mergeit = "r1"} else {mergeit = paste(mergeit,",r",i, sep="")}
6476
dothis = paste("r",i,"=align(demfiles[",i,"], refimg)", sep="")
6577
eval(parse(text=dothis))
66-
if(i == len){mergeit = paste("big = raster::mosaic(",mergeit,",fun=mean,na.rm=T,tolerance=0.5)", sep="")}
78+
if(i == len){mergeit = paste("big = raster::mosaic(",mergeit,",fun=mean,na.rm=T,tolerance=0.5, filename=outfile, format='GTiff', datatype = 'INT2S',overwrite=T,options=c('COMPRESS=NONE'))", sep="")}
6779
}
6880

69-
7081
print("Creating DEM mosaic")
7182
eval(parse(text=mergeit))
72-
73-
print("Writing DEM mosaic")
74-
outfile = file.path(dir,"dem_mosaic.tif")
75-
raster::writeRaster(big, outfile, format="GTiff", datatype = "INT2S",overwrite=T,options=c("COMPRESS=NONE"))
7683
unlink(demfiles)
7784

7885
}

R/reprojectDEM.r

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,33 @@
44
#' conform to the properties of an image file prior to using it as an input to the 'MSScvm' masking function
55
#' @param demFile filename (character). Full path to DEM file.
66
#' @param projRef filename (character). Full path to an image file produced by the \code{\link{MSSunpack}} function.
7+
#' @param srcNodata numeric. Specify the background value in the input DEM. If there is no background value, use NA (default)
8+
#' @param dstNodata numeric. Specify the value to represent background pixels in the reprojected DEM. -32768 is the default
79
#' @details The DEM file will be adjusted to match the projection and pixel resolution of the 'proRef' image.
810
#' @return A GeoTIFF raster file with '_reprojected.tif' replacing the last 4 characters of the input DEM filename
911
#' @seealso \code{\link{mosaicDEMs}}
1012
#' @examples \dontrun{
1113
#'
1214
#' reprojectDEM(demFile = "C:/mss/dem/wrs1_p036r032_dem.tif",
13-
#' projRef = "C:/mss/LM10360321973191AAA04/LM10360321973191AAA04_dn.tif")
15+
#' projRef = "C:/mss/LM10360321973191AAA04/LM10360321973191AAA04_dn.tif",
16+
#' srcNodata= -9999, dstNodata= -32768)
1417
#' }
1518
#' @export
1619

17-
reprojectDEM = function(demFile, projRef){
20+
reprojectDEM = function(demFile, projRef, srcNodata=NA, dstNodata=-32768){
1821

1922
template = raster::raster(projRef) #read in the projection reference image
2023
reso = raster::xres(template) #get the pixel resolution
2124
proj = raster::projection(template) #get the projection
2225

23-
print(paste("Reprojecting file:",demFile))
26+
print(paste("Reprojecting",demFile))
2427
bname = basename(demFile) #get the basename of the dem file
2528
extension = substr(bname,(nchar(bname)-3),nchar(bname)) #extract the extension of the dem file
2629
dstfile = sub(extension, "_reprojected.tif", demFile) #define the filename
2730

2831
gdalUtils::gdalwarp(srcfile=demFile, dstfile=dstfile,
2932
t_srs=proj, of="GTiff",
30-
r="near", multi=T,
33+
r="near", multi=T, srcnodata=srcNodata, dstnodata=dstNodata, overwrite=TRUE,
3134
tr=c(reso,reso), co="INTERLEAVE=BAND") #reproject the image using gdalwarp through gdalUtils
3235

3336
}

man/mosaicDEMs.Rd

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
\alias{mosaicDEMs}
55
\title{Create a DEM mosaic from a direcory of DEM's}
66
\usage{
7-
mosaicDEMs(dir, projRef, NAvalue)
7+
mosaicDEMs(dir, projRef, srcNodata = NA, dstNodata = -32768)
88
}
99
\arguments{
1010
\item{dir}{directory name (character). Full path to a directory containing digital elevation model (DEM) files to be mosaiced.}
1111
1212
\item{projRef}{filename (character). Full path to an image file produced by the \code{\link{MSSunpack}} function.}
1313
14-
\item{NAvalue}{numeric. What is the background value of the DEM files in the directory.}
14+
\item{srcNodata}{numeric. What is the background value of the DEM files in the directory. If there is no background value, use NA (default)}
15+
16+
\item{dstNodata}{numeric. Specify the value to represent background pixels in the mosaic DEM. -32768 is the default}
1517
}
1618
\value{
1719
A GeoTIFF raster file representing the union of all individual DEM files found in the provided directory path. The mosaic file will be written to the
@@ -23,7 +25,7 @@ A helper function to create the large-extent DEM file required by the 'MSScvm' f
2325
\details{
2426
The provided directory path should only contain decompressed digital elevation files from the same source (SRTM, NED, GTOPO, etc).
2527
The function will search the directory and include all files found in the mosaic. It is important that each file have the same background value
26-
and that it is correctly assigned to the 'NAvalue' parameter, if not, intersection between DEMs could have unexpected results.
28+
and that it is correctly assigned to the 'srcNodata' parameter, if not, intersection between DEMs could have unexpected results.
2729
Each individual DEM file will be adjusted to match the projection and pixel resolution of the 'proRef' image.
2830
Then they will be merged using the mean value of intersecting pixels.
2931
}
@@ -32,7 +34,7 @@ Then they will be merged using the mean value of intersecting pixels.
3234
3335
mosaicDEMs(dir = "C:/mss/dems",
3436
projRef = "C:/mss/LM10360321973191AAA04/LM10360321973191AAA04_dn.tif",
35-
NAvalue = -32768)
37+
srcNodata = -9999, dstNodata= -32768)
3638
}
3739
}
3840
\seealso{

0 commit comments

Comments
 (0)