library(aqp)
library(soilDB)
library(raster)
library(rgeos)
library(sharpshootR)
library(cluster)
library(reshape2)
# define a bounding box: xmin, xmax, ymin, ymax
#
# +-------------------(ymax, xmax)
# | |
# | |
# (ymin, xmin) ----------------+
b <- c(-123.14851, -123.13538, 46.79967, 46.80866)
# convert bounding box to WKT
bbox.wkt <- writeWKT(as(extent(b), 'SpatialPolygons'))
# compose query, using WKT BBOX as filtering criteria
q <- sprintf("SELECT mukey, co.cokey, compname, comppct_r AS comppct,
chkey, hzname, hzdept_r, hzdepb_r, sandtotal_r AS sand, silttotal_r AS silt, claytotal_r AS clay
FROM component AS co
JOIN chorizon AS hz ON co.cokey = hz.cokey
WHERE mukey IN (SELECT DISTINCT mukey FROM SDA_Get_Mukey_from_intersection_with_WktWgs84('%s') )
ORDER BY mukey, co.cokey, comppct_r DESC", bbox.wkt)
# send query, results are tabular data only
res <- SDA_query(q)
# check
head(res)
## mukey cokey compname comppct chkey hzname hzdept_r hzdepb_r sand silt clay
## 1 2454689 20115516 Melbourne 100 59024749 H1 0 15 20.0 49.0 31
## 2 2454689 20115516 Melbourne 100 59024750 H2 15 28 20.0 49.0 31
## 3 2454689 20115516 Melbourne 100 59024751 H3 28 137 16.9 48.1 35
## 4 2454689 20115516 Melbourne 100 59024752 H4 137 152 33.3 31.7 35
## 5 2454690 20115529 Melbourne 100 59024764 H1 0 15 20.0 49.0 31
## 6 2454690 20115529 Melbourne 100 59024765 H2 15 28 20.0 49.0 31
# promote to SoilProfileCollection for sketches and other goodness
depths(res) <- cokey ~ hzdept_r + hzdepb_r
# move site-level attr up
site(res) <- ~ mukey + compname + comppct
# rescale sand, silt, clay values for mixing into sRGB colors
sand <- res$sand / max(res$sand, na.rm = TRUE)
silt <- res$silt / max(res$silt, na.rm = TRUE)
clay <- res$clay / max(res$clay, na.rm = TRUE)
# replace NA with a value that will approximate "light grey" when mixed
sand <- ifelse(is.na(sand), 0.9, sand)
silt <- ifelse(is.na(silt), 0.9, silt)
clay <- ifelse(is.na(clay), 0.9, clay)
# mix proportions into sRGB colors
res$texture_color <- rgb(red=sand, green = silt, blue = clay, maxColorValue = 1)
## kind of a hack...
# build a very rough legend for expected texture classes
# based on mixing of sRGB colors and rough estimates of sand, silt, clay percentages
sand.leg <- c(80, 65, 25, 22) / max(res$sand, na.rm = TRUE)
silt.leg <- c(15, 20, 55, 40) / max(res$silt, na.rm = TRUE)
clay.leg <- c(5, 15, 20, 38) / max(res$clay, na.rm = TRUE)
col.legend <- rgb(red=sand.leg, green = silt.leg, blue = clay.leg, maxColorValue = 1)
texture.legend <- c('loamy sand', 'sandy loam', 'silt loam', 'clay loam')
# tighten margins and plot all three fractions
par(mar=c(0,0,3,1), mfrow=c(3, 1))
plotSPC(res, color='sand', label='compname', name='hzname', col.label = 'Percent Sand')
plotSPC(res, color='silt', label='compname', name='hzname', col.label = 'Percent Silt')
plotSPC(res, color='clay', label='compname', name='hzname', col.label = 'Percent Clay')
# plot mixed colors with legend
par(mar=c(0,0,1,1), mfrow=c(1, 1))
plotSPC(res, color='texture_color', label='compname', name='hzname')
legend('bottom', legend = texture.legend, pch=22, pt.bg = col.legend, pt.cex = 2, bty='n', horiz = TRUE)
# there are likely many versions of the same component
# generate an index to unique components as defined by the following horizon level attributes
idx <- unique(res, vars=c('hzdept_r', 'hzdepb_r', 'sand', 'silt', 'clay'))
res.unique <- res[idx, ]
# ah, much more useful
plotSPC(res.unique, color='texture_color', label='compname', name='hzname')
legend('bottom', legend = texture.legend, pch=22, pt.bg = col.legend, pt.cex = 2, bty='n', horiz = TRUE)
# quick comparison of profiles based on variation in:
# sand and clay
# to a depth of 150cm
# no depth-weighting
d <- profile_compare(res.unique, vars=c('sand', 'clay'), max_d=150, k=0)
# hand the profiles from a dendrogam, built from divisive hierarchical clustering
par(mar=c(0,0,3,3))
plotProfileDendrogram(res.unique, diana(d), scaling.factor = 1.1, color='texture_color', width=0.25, y.offset = 5, axis.line.offset = -1, label='compname', name='hzname')
# rough legend
legend('bottom', legend = texture.legend, pch=22, pt.bg = col.legend, pt.cex = 2, bty='n', horiz = TRUE)
# eval texture via 0-25cm weighted mean sand, silt, clay
a <- slab(res, cokey ~ sand + silt + clay, slab.structure = c(0, 25), slab.fun = mean, na.rm=TRUE)
ssc <- dcast(a, cokey ~ variable, value.var = 'value')
ssc <- na.omit(ssc)
names(ssc) <- toupper(names(ssc))
textureTriangleSummary(ssc, cex=0.5, p = c(0.10, 0.5, 0.9), main = '0-25cm Weighted Mean')