|
Hi Taïs
Thanks for testing. As Moritz mentioned, the important parameter in spatial kernel density is the bandwidth. Here attached is an improved script that uses the spatialEco R package (instead of density.ppp from spatstat). To run this, you'll need to install spatialEco in your R environment.
This package allows to specify both the bandwidth and the target raster extents and resolution. In this script I take the extents and resolution from the GRASS region. Bandwidth is specified on the command line. So to try this, in your running GRASS session:
Rscript kernel_density.R <GRASS point vector> <weight column> <bandwidth>
I also attached two images in a test I did, with bandwidths of 10,000 and 20,000.
Hope this helps, Micha
On 10/25/19 12:17 PM, Taïs wrote:
-- Micha Silver Ben Gurion Univ. Sde Boker, Remote Sensing Lab cell: +972-523-665918 |
# Weighted Kernel Density in R
# Using the spatialEco package
# execute from a GRASS session
# Command line arguments: GRASS point vector, column of weights
#####################################################################
suppressMessages(library(rgrass7, quietly=TRUE))
suppressMessages(library(spatialEco, quietly = TRUE))
suppressMessages(library(sp, quietly = TRUE))
suppressMessages(library(raster, quietly = TRUE))
# Test case, in GRASS location nc_basic_spm, using the schools vector
# This vector has attribut CORECAPACI, used as weight in this case
args = commandArgs(trailingOnly=TRUE)
if (length(args) < 3) {
cat("Syntax:\nRscript kernel_density.R <GRASS point vector> <weight attribute> <bandwidth>")
print("Exiting...")
quit(save="no")
} else {
input_vect = args[1]
output_rast = paste0(input_vect, "_density")
weights_col = args[2]
bandwidth = as.integer(args[3])
}
use_sp()
pts = readVECT(input_vect)
# Check geometry type and weight attribute column
if (class(pts)!= "SpatialPointsDataFrame") {
print("Wrong geometry type. Must be POINT")
quit(save="no")
}
weights_idx = which(names(pts) == weights_col)
if (length(weights_idx) == 0) {
print(paste("No attribute column:", weights_col))
quit(save="no")
}
# Remove NA
pts = pts[!is.na(pts[[weights_idx]]),]
wts = pts[[weights_idx]]
print(paste("Using:", length(wts), "points"))
# Prepare newgrid object (as R raster)
execGRASS(cmd = "r.mapcalc", parameters=list(expression = 'tmp_one = 1'))
newgrid = raster(readRAST("tmp_one"))
execGRASS(cmd = 'g.remove', parameters=list(type = 'rast', name = 'tmp_one'), flags = 'f')
# Density (default Gaussian kernel)
pts_dens = sp.kde(x = pts, y = wts,
bw = bandwidth, newdata = newgrid)
png(paste("density_plot", as.character(bandwidth), ".png"))
plot(pts_dens, main = paste(input_vect, "Density"),
sub = paste("bw:", as.character(bandwidth)))
dev.off()
# Convert to SGDF to save back to GRASS
pts_sgdf = as(pts_dens, "SpatialGridDataFrame")
writeRAST(x = pts_sgdf, vname = output_rast, overwrite = TRUE)
_______________________________________________ grass-user mailing list [email protected] https://lists.osgeo.org/mailman/listinfo/grass-user
