R/spplot.R

Defines functions panel.ggmap panel.RgoogleMaps addNAemptyRowsCols colorkey.factor bbexpand longlat.scales spplot.key sp.theme layout.scale.bar layout.north.arrow mapLegendGrob SpatialPolygonsRescale SpatialPolygons2Grob panel.pointsplot panel.gridplot create.z spplot.points spplot.polygons spplot.grid getFormulaLevelplot sppanelList sp.panel.layout sp.text sp.grid sp.points sp.lines sp.polygons

Documented in bbexpand layout.north.arrow layout.scale.bar longlat.scales mapLegendGrob panel.ggmap panel.gridplot panel.pointsplot panel.RgoogleMaps SpatialPolygonsRescale sp.grid sp.lines sp.panel.layout spplot.grid spplot.key spplot.points spplot.polygons sp.points sp.polygons sp.text sp.theme

setMethod("sppanel", "SpatialPolygons",
  function(obj, col = 1, fill = "transparent", ...) {
	if (is.character(obj))
		obj = get(obj)
	if (!is(obj, "SpatialPolygons"))
		stop(paste(
		"object extending class SpatialPolygons expected; got class",
		class(obj)))
	else
		obj = as(obj, "SpatialPolygons")
	if (get_Polypath()) {
		lo = length(obj)
		obj = as(as(obj, "SpatialLines"), "SpatialPointsDataFrame")
		cc = coordinates(obj)
		#id = as.numeric(obj$Line.NR)
		id = as.numeric(obj$Lines.NR * max(obj$Line.NR) + (obj$Line.NR - 1))
		if (length(fill) > 1 || length(col) > 1) {
			fill = rep(fill, length.out = lo)
			col = rep(col, length.out = lo)
			for (i in 1:lo) {
				sel = obj$Lines.NR == i
				grid.path(cc[sel,1], cc[sel,2], id[sel], 
					default.units = "native", 
					gp = gpar(col = col[i], fill = fill[i], ...))
			}
		} else 
			grid.path(cc[,1], cc[,2], id, default.units = "native",
				gp = gpar(col = col, fill = fill, ...))
	} else {
		sp.polygon3 = function(x, col, fill, ...) { 
			cc = slot(x, "coords")
			grid.polygon(cc[,1], cc[,2], default.units = "native", 
				gp = gpar(col = col, fill = fill, ...))
			panel.lines(cc, col = col, ...)
		}
		pls = slot(obj, "polygons")
   		pO <- slot(obj, "plotOrder")
		if (length(fill) != length(pO)) 
			fill <- rep(fill[1], length(pO))
		for (i in pO) {
			Srs <- slot(pls[[i]], "Polygons")
			pOi <- slot(pls[[i]], "plotOrder")
			for (j in pOi)
				sp.polygon3(Srs[[j]], col = col, fill = fill[i], ...)
		}
	}
})

# backward compatibility:
sp.polygons = function(obj, col = 1, fill = "transparent",...) 
	sppanel(obj, col = col, fill = fill, ...)

setMethod("sppanel", "SpatialLines", 
  function (obj, col = 1, ...) {
    ## contributed by Josh O'Brien, Mar 15, 2015
	lo <- length(obj@lines)
	col <- rep(col, length.out = lo)
	lapply(seq_len(lo), function(ii) sppanel(obj@lines[[ii]], col = col[ii], ...))
})

setMethod("sppanel", "Lines",
  function (obj, col = 1, ...) lapply(obj@Lines, sppanel, col = col, ...))

setMethod("sppanel", "Line",
  function (obj, col = 1, ...) panel.lines(coordinates(obj), col = col, ...))

# backward compatibility:
sp.lines = function(obj, col = 1,...) sppanel(obj, col = col,...)

setMethod("sppanel", "SpatialPoints",
	function(obj, pch = 3, ...)
		panel.points(coordinates(obj), pch = pch, ...))
# backward compatibility:
sp.points = function(obj, pch=3, ...) sppanel(obj, pch = pch, ...)

sp.grid = function(obj, col = 1, alpha = 1, ..., at = pretty(obj[[1]]),
		col.regions = col) {
	xy = coordinates(obj)
	if (length(col) > 1 && ("data" %in% slotNames(obj))) {
		z = obj[[1]]
		if (is.factor(z))
			col = col[z]
		else  # cut:
    		col = level.colors(z, at, col.regions, colors = TRUE)
	}
	gt = as(getGridTopology(obj), "data.frame")
	grid.rect(x = xy[,1], y = xy[,2], width = gt$cellsize[1],
		height = gt$cellsize[2], default.units = "native",
		gp = gpar(fill = col, col = NA, alpha = alpha))
}
setMethod("sppanel", "SpatialPixels", sp.grid)
setMethod("sppanel", "SpatialGrid", sp.grid)

sp.text = function(loc, txt, ...) {
	if (!is.numeric(loc))
		stop("loc (first argument) should be numeric, indicating text locations")
	if (length(loc) == 2)
		panel.text(loc[1], loc[2], txt, ...)
	else if (is.matrix(loc) && ncol(loc) == 2 && nrow(loc) == length(txt))
		panel.text(loc[,1], loc[,2], txt, ...)
	else
		stop("loc and txt have non-matching dimensions")
}
setMethod("sppanel", "character", function(obj,txt, ...) sp.text(obj, txt, ...))

sp.panel.layout = function(lst, p.number, ...) { # now obsolete...
	.Deprecated("sppanel")
	sp.panel0 = function(x, first = FALSE, ...) {
		if (inherits(x, "list")) {
			if (!is.null(x$which) && is.na(match(p.number, x$which)))
				return()
			# print(paste(class(x), "first val", first, "first obj", x$first))
			if (!is.null(x$first)) {
				if (x$first == first)
					do.call(x[[1]], x[2:length(x)])
			} else if (!first)
				do.call(x[[1]], x[2:length(x)])
		} 
	}
	if (!is.null(lst$which) && is.na(match(p.number, lst$which)))
		return()
	else
		lst$which = NULL
	if (is.null(lst))
		return()
	if (inherits(lst, "list")) {
		if (inherits(lst[[1]], "list")) 
			lapply(lst, sp.panel0, ...)
		else
			sp.panel0(lst, ...)
	} else
		stop(paste("expected object of class list; got object of class", class(lst)))
}

setMethod("sppanel", "NULL", function(obj,...) { })

sppanelList = function(obj, p.number, first, ...) {
	missingFirst = missing(first)
	if (length(obj) == 1 & is.null(obj[[1]]))
		return()
	if (!is.null(obj$which) && is.na(match(p.number, obj$which)))
		return() # false panel
	else 
		obj$which = NULL # continue: either all panels, or right panel
	if (is.list(obj[[1]])) # list-of-lists, recurse:
		return(lapply(obj, sppanel, p.number = p.number, first = first, ...))
	opaque = function(x) (is(x, "SpatialPolygons") || is(x, "SpatialGrid") || is(x, "SpatialPixels"))
	if (is.character(obj[[1]]) || is.function(obj[[1]])) {
		if (is.null(obj$first))
			obj$first = opaque(obj[[2]]) # default: grids/polygons behind, rest front
		if (missingFirst) # meaning: do plot it
			first = obj$first
		if (obj$first == first) {
			obj$first = NULL
			do.call(obj[[1]], obj[-1], ...)
		}
	} else {
		sp = sapply(obj, is, "Spatial")
		stopifnot(any(sp))
		lapply(obj[sp], function(x) { 
			if (missingFirst || identical(obj$first, first) || opaque(x) == first)
				do.call(sppanel, append(x, obj[!sp]), ...)
		})
	}
}
setMethod("sppanel", "list", sppanelList)

getFormulaLevelplot = function(sdf, zcol) {
	if (length(zcol) > 1)
		as.formula(paste("z~", paste(dimnames(coordinates(sdf))[[2]], 
			collapse = "+"), "|name"))
	else {
		if (!is.character(zcol)) 
			zcol = names(sdf)[zcol]
		as.formula(paste(zcol, "~", paste(dimnames(coordinates(sdf))[[2]],
			collapse = "+")))
	}
}

spplot.grid = function(obj, zcol = names(obj), ..., names.attr, 
		scales = list(draw = FALSE), xlab = NULL, ylab = NULL, 
		aspect = mapasp(obj,xlim,ylim), panel = panel.gridplot, sp.layout = NULL, formula, 
		xlim = bbox(obj)[1,], ylim = bbox(obj)[2,], checkEmptyRC = TRUE,
		col.regions = get_col_regions()) {
	if (is.null(zcol)) stop("no names method for object")
	if (checkEmptyRC)
		sdf = addNAemptyRowsCols(obj) # returns SpatialPointsDataFrame
	else
		sdf = as(obj, "SpatialPointsDataFrame")
	if (missing(formula))
		formula = getFormulaLevelplot(sdf, zcol)
	if (length(zcol) > 1) {
		sdf = spmap.to.lev(sdf, zcol = zcol, names.attr = names.attr)
		zcol2 = "z"
	} else
		zcol2 = zcol
    if (exists("panel.levelplot.raster")) {
        opan <- lattice.options("panel.levelplot")[[1]]
        lattice.options("panel.levelplot"="panel.levelplot.raster")
#       cat("using raster panel\n")
    }
	scales = longlat.scales(obj, scales, xlim, ylim)
	args = append(list(formula, data = as(sdf, "data.frame"), 
		aspect = aspect, panel = panel, xlab = xlab, ylab = ylab, scales = scales,
		sp.layout = sp.layout, xlim = xlim, ylim = ylim, col.regions = col.regions), 
		list(...))
	# deal with factor variables:
	if (all(unlist(lapply(obj@data[zcol], is.factor)))) {
		#if (!is.null(args$col.regions) &&
		#		nlevels(obj@data[[zcol[1]]]) != length(args$col.regions))
		#	stop("length of col.regions should match number of factor levels")
		args$data[[zcol2]] = as.numeric(args$data[[zcol2]])
		if (is.null(args$colorkey) || (is.logical(args$colorkey) && args$colorkey)
				|| (is.list(args$colorkey) && is.null(args$colorkey$at) && 
					is.null(args$colorkey$labels))) {
			if (!is.list(args$colorkey))
				args$colorkey = list()
			ck = args$colorkey
			args$colorkey = NULL
			args = append(args, colorkey.factor(obj[[zcol[1]]], ck))
		} else
			args = append(args, colorkey.factor(obj[[zcol[1]]], ck, FALSE))
	}
	ret = do.call(levelplot, args)
    if (exists("panel.levelplot.raster"))
        lattice.options("panel.levelplot" = opan)
	ret 
}

setMethod("spplot", signature("SpatialPixelsDataFrame"), spplot.grid)
setMethod("spplot", signature("SpatialGridDataFrame"), 
	function(obj, ...) spplot.grid(as(obj, "SpatialPixelsDataFrame"), ...))

spplot.polygons = function(obj, zcol = names(obj), ..., names.attr, 
		scales = list(draw = FALSE), xlab = NULL, ylab = NULL, 
		aspect = mapasp(obj,xlim,ylim), 
		panel = panel.polygonsplot, sp.layout = NULL, formula, 
		xlim = bbox(obj)[1,], ylim = bbox(obj)[2,],
		col.regions = get_col_regions()) {

	if (is.null(zcol)) stop("no names method for object")
	sdf = as(obj, "data.frame")
	if (is(obj, "SpatialPolygonsDataFrame"))
		labpts = coordinates(obj)
	else {
		# get first points of each lines object:
		n = length(obj@lines)
		labpts = matrix(unlist(lapply(obj@lines, function(x) 
			lapply(x@Lines[1], function(x) coordinates(x)[1,]))), 
				n, 2, byrow=TRUE) 
	}
	dimnames(labpts)[[2]] = c("xlabelpoint", "ylabelpoint")
	sdf = as.data.frame(cbind(labpts, sdf))
	coordinates(sdf) = c("xlabelpoint", "ylabelpoint")
	if (missing(formula))
		formula = getFormulaLevelplot(sdf, zcol)
	if (length(zcol) > 1) {
		sdf = spmap.to.lev(sdf, zcol = zcol, names.attr = names.attr)
		zcol2 = "z"
	} else
		zcol2 = zcol
	if (is(obj, "SpatialPolygonsDataFrame"))
		grid.polygons = as(obj, "SpatialPolygons")
	else
		grid.polygons = as(obj, "SpatialLines")
	scales = longlat.scales(obj, scales, xlim, ylim)

	args = append(list(formula, data = as(sdf, "data.frame"),
		aspect = aspect, grid.polygons = grid.polygons, panel =
		panel, xlab = xlab, ylab = ylab, scales = scales,
		sp.layout = sp.layout, xlim = xlim, ylim = ylim,
		col.regions = col.regions), list(...))
	if (all(unlist(lapply(obj@data[zcol], is.factor)))) {
		#if (!is.null(args$col.regions) &&
		#		nlevels(obj@data[[zcol[1]]]) != length(args$col.regions))
		#	stop("length of col.regions should match number of factor levels")
		args$data[[zcol2]] = as.numeric(args$data[[zcol2]])
		if (is.null(args$colorkey) 
				|| (is.logical(args$colorkey) && args$colorkey)
				|| (is.list(args$colorkey) && is.null(args$colorkey$at) && 
					is.null(args$colorkey$labels))) {
			if (!is.list(args$colorkey))
				args$colorkey = list()
			ck = args$colorkey
			args$colorkey = NULL
			args = append(args, colorkey.factor(obj[[zcol[1]]], ck))
		} else
			args = append(args, colorkey.factor(obj[[zcol[1]]], ck, FALSE))
	}
	do.call(levelplot, args)
}

setMethod("spplot", signature("SpatialPolygonsDataFrame"), spplot.polygons)
setMethod("spplot", signature("SpatialLinesDataFrame"), spplot.polygons)

spplot.points = function(obj, zcol = names(obj), ..., names.attr, 
		scales = list(draw = FALSE), xlab = NULL, ylab = NULL, 
		aspect = mapasp(obj,xlim,ylim), panel = panel.pointsplot,
		sp.layout = NULL, identify = FALSE, formula,
		xlim = bbexpand(bbox(obj)[1,], 0.04), 
		ylim = bbexpand(bbox(obj)[2,], 0.04),
		edge.col = "transparent", colorkey = FALSE,
		col.regions = get_col_regions()) 
{

	if (is.null(zcol)) stop("no names method for object")
	dots = list(...)
	sdf = obj
	if (!is.character(zcol)) 
		zcol = names(sdf)[zcol]
	# create formula:
	if (missing(formula)) {
		if (length(zcol) > 1) {
			formula = as.formula(paste(paste(dimnames(coordinates(sdf))[[2]][2:1], 
				collapse = "~"), "|name"))
			sdf = spmap.to.lev(sdf, zcol = zcol, names.attr = names.attr)
		} else {
			if (!is.character(zcol)) 
				zcol = names(sdf)[zcol]
			ccn = dimnames(coordinates(sdf))[[2]]
			formula = as.formula(paste(ccn[2], "~", ccn[1]))
		}
	}
	scales = longlat.scales(obj, scales, xlim, ylim)
	args.xyplot = append(list(formula, data = as(sdf, "data.frame"), 
		panel = panel, aspect = aspect, scales = scales, 
		xlab = xlab, ylab = ylab, sp.layout = sp.layout,
		xlim = xlim, ylim = ylim, edge.col = edge.col,
		col.regions = col.regions), dots)
	z = create.z(as(obj, "data.frame"), zcol)
	args.xyplot = fill.call.groups(args.xyplot, z = z, edge.col = edge.col, 
		colorkey = colorkey, ...)
	# debug:
	#print(args.xyplot)
	plt = do.call(xyplot, args.xyplot)
	if (!(is.logical(identify) && identify==FALSE) && interactive()) {
		print(plt)
		if (!(is.numeric(identify) && length(identify) == 2))
			identify = c(1,1)
		trellis.focus("panel", identify[1], identify[2])
		labels = row.names(as(sdf, "data.frame"))
		cat("left-mouse to identify points; right-mouse to end\n")
		cc = coordinates(obj)
		ret = panel.identify(cc[,1], cc[,2], labels)
		trellis.unfocus()
		return(ret)
	} else
		plt
}
setMethod("spplot", signature("SpatialPointsDataFrame"), spplot.points)

setMethod("spplot", signature("SpatialMultiPointsDataFrame"), 
	function(obj, ...) spplot.points(as(obj, "SpatialPointsDataFrame"), ...))

create.z = function(df, zcol) {
	if (is.logical(df[[zcol[1]]])) {
		z = stack(df[zcol])[[1]]
		z = as.factor(z)
	} else if (is.numeric(df[[zcol[1]]]))
		z = stack(df[zcol])[[1]]
	else if (is.factor(df[[zcol[1]]])) {
		lev = levels(df[[zcol[1]]])
		z = factor(as.vector(sapply(df[zcol], as.character)), levels = lev)
	} else
		stop("no support for variable of this type")
	z
}

panel.gridplot = function(x, y, z, subscripts, ..., sp.layout) {
	sppanel(list(sp.layout), panel.number(), first = TRUE)
	panel.levelplot(x, y, z, subscripts, ...)
	sppanel(list(sp.layout), panel.number(), first = FALSE)
}

panel.polygonsplot =
function (x, y, z, subscripts, at = pretty(z), shrink, labels = NULL, 
   		label.style = c("mixed", "flat", "align"), contour = FALSE, 
   		region = TRUE, col = add.line$col, lty = add.line$lty, 
		lwd = add.line$lwd, 
   		cex = add.text$cex, font = add.text$font, 
		fontfamily = add.text$fontfamily, 
   		fontface = add.text$fontface, col.text = add.text$col, ..., 
   		col.regions = regions$col, alpha.regions = regions$alpha, 
		grid.polygons, sp.layout) 
{
	regions <- trellis.par.get("regions")
	add.line <- trellis.par.get("add.line")
	add.text <- trellis.par.get("add.text")
	numcol <- length(at) - 1
	numcol.r <- length(col.regions)
	col.regions <- if (numcol.r <= numcol) 
			rep_len(col.regions, numcol)
   		else col.regions[floor(1 + (1:numcol - 1) * (numcol.r - 1)/(numcol - 1))]
	zcol <- rep(NA, length(z))
	for (i in seq_along(col.regions)) zcol[!is.na(x) & !is.na(y) & 
      			!is.na(z) & z >= at[i] & z < at[i + 1]] <- i
	label.style <- match.arg(label.style)
	x <- as.numeric(x[subscripts])
	y <- as.numeric(y[subscripts])
	z <- as.numeric(z[subscripts])
	zcol <- as.numeric(zcol[subscripts])

	sppanel(list(sp.layout), panel.number(), first = TRUE)
	if (any(subscripts)) {
		if (is(grid.polygons, "SpatialLines")) {
			sp.lines3 = function(x, col, ...) panel.lines(coordinates(x), col = col, ...)
			sp.lines2 = function(x, col, ...) lapply(x@Lines, sp.lines3, col, ...)
			for (i in 1:length(grid.polygons@lines))
				sp.lines2(grid.polygons@lines[[i]], col = col.regions[zcol[i]], lwd = lwd, lty = lty, ...)
		} else {
			pls = slot(grid.polygons, "polygons")
   			pO = slot(grid.polygons, "plotOrder")
			col = rep(col, length.out = length(grid.polygons))
   			for (i in pO) {
				if (get_Polypath()) {
					obj = as(as(grid.polygons[i,], "SpatialLines"),
							"SpatialPointsDataFrame")
					cc = coordinates(obj)
					id = as.numeric(obj$Line.NR)
					fill = col.regions[zcol[i]]
					alpha = alpha.regions
					grid.path(cc[,1], cc[,2], id, default.units = "native",
						gp = gpar(col = col[i], fill = fill, alpha = alpha, 
							lwd = lwd, lty = lty, ...))
				} else {
       				Srs <- slot(pls[[i]], "Polygons")
       				pOi <- slot(pls[[i]], "plotOrder")
       				for (j in pOi) {
						coords = slot(Srs[[j]], "coords")
						if (slot(Srs[[j]], "hole")) {
							bg = trellis.par.get()$background
							if (bg$col == "transparent")
								fill = "white"
							else
								fill = bg$col
							alpha = bg$alpha
						} else {
							fill = col.regions[zcol[i]]
							alpha = alpha.regions
						}
						gp = gpar(fill = fill, alpha = alpha, col = col, lwd = lwd, lty = lty)
						grid.polygon(coords[,1], coords[,2], default.units = "native", 
							gp = gp)
					}
				}
   			}
		}
	}
	sppanel(list(sp.layout), panel.number(), first = FALSE)
}

panel.pointsplot = function(sp.layout, x, y, subscripts, groups, col, cex,
		pch, ...) {
	sppanel(list(sp.layout), panel.number(), first = TRUE)
	lpoints(x, y, fill = groups[subscripts], col = col[subscripts], 
		cex = cex[subscripts], pch = pch[subscripts], ...)
	sppanel(list(sp.layout), panel.number(), first = FALSE)
}

SpatialPolygons2Grob = function(obj, fill) {
	if (!is(obj, "SpatialPolygons"))
		stop("object is not of class SpatialPolygons")
	x = numeric(0)
	y = numeric(0)
	id = integer(0)
	pls = slot(obj, "polygons")
   	pO <- slot(obj, "plotOrder")
	n = 0
   	for (i in pO) {
   		Srs <- slot(pls[[i]], "Polygons")
   		pOi <- slot(pls[[i]], "plotOrder")
   		for (j in pOi) {
			n = n + 1
			cc = slot(Srs[[j]], "coords")
			x = c(x, cc[,1])
			y = c(y, cc[,2])
			id = c(id, rep(n, nrow(cc)))
		}
	}
	polygonGrob(x=x, y=y, id=id, gp = gpar(fill = fill))
}

SpatialPolygonsRescale = function(obj, offset, scale = 1, fill = "black", col = "black", plot.grid = TRUE, ...) {
	if (!is(obj, "SpatialPolygons"))
		stop("object is not of class SpatialPolygons")
	if (length(offset) != 2)
		stop("offset should have length 2")
	if (is.list(offset))
		offset = c(offset[[1]], offset[[2]])
	if (length(scale) == 1)
		scale = rep(scale,2)
	pls = slot(obj, "polygons")
   	pO = slot(obj, "plotOrder")
	fill = rep_len(fill, length(pls))
   	for (i in pO) {
   		Srs <- slot(pls[[i]], "Polygons")
   		pOi <- slot(pls[[i]], "plotOrder")
   		for (j in pOi) {
			cc = slot(Srs[[j]], "coords")
			x = offset[1] + (cc[,1] * scale[1])
			y = offset[2] + (cc[,2] * scale[2])
			if (plot.grid) {
				grid.polygon(x, y, default.units = "native", 
					gp = gpar(col = col, fill = fill[i], ...))
			} else {
				polygon(x, y, col = fill[i])
				lines(x, y, col = col)
			}
		}
	}
}

mapLegendGrob <- function(obj, widths = unit(1, "cm"), heights = unit(1, "cm"),
		fill = "black", just = "right") {
	grb = SpatialPolygons2Grob(obj, fill)
	key.layout <- grid.layout(nrow = 1, ncol = 1, widths = widths,
					heights = heights, respect = TRUE, just = just)
	key.gf <- frameGrob(layout = key.layout)
	key.gf <- placeGrob(key.gf,
				  rectGrob(gp = gpar(fill = "transparent", col = NULL)),
				  row = NULL, col = NULL)
	key.gf <- placeGrob(key.gf, grb, row = 1, col = 1)
	key.gf
}

layout.north.arrow = function(type = 1) {
	if (type == 1) {
		x1 = c(0.1653, 0.2241, 0.2241, 0.2830, 0.1947, 0.1065, 0.1653, 0.1653)
		x2 = c(0, 0.0967, 0.0967, 0.2928, 0.3908, 0.3908, 0.2928, 0.2928, 0.1032, 0, 0)
		y1 = c(0, 0, 0.8823, 0.8235, 1, 0.8235, 0.8823, 0)
		y2 = c(0.2352, 0.2352, 0.5686, 0.2352, 0.2352, 0.7189, 0.7189, 0.3986, 0.7189, 0.7189, 0.2352 )
		return(SpatialPolygons(list(Polygons(list(Polygon(cbind(x1,y1)), Polygon(cbind(rev(x2),rev(y2)))), ID="north"))))
	}
	if (type == 2) {
		x = c(0.143,0.143,0.0143,0.207,0.400,0.271,0.271,0.143)
		y = c(0,0.707,0.707,0.964,0.707,0.707,0.00,0.0)
		return(SpatialPolygons(list(Polygons(list(Polygon(cbind(x,y))), ID="north"))))
	}
	stop("unknown value for type")
}

layout.scale.bar = function(height = 0.05) {
	x1 = c(0, 0.5, 0.5, 0, 0)
	y1 = c(0, 0, height, height, 0)
	x2 = x1 + 0.5
	y2 = y1
	SpatialPolygons(list(Polygons(list(Polygon(cbind(x1,y1))), ID="left"), 
			Polygons(list(Polygon(cbind(rev(x2),rev(y2)))), ID="right")))
}
# scale.bar = .scale.bar()

sp.theme = function(set = FALSE, regions = list(col = bpy.colors(100)), ...) {
	lst = list(regions = regions, ...)
	if (set)
		trellis.par.set(lst)
	else
		lst
}

spplot.key = function(sp.layout, rows = 1, cols = 1) {
	for (i in seq_along(rows)) {
		for (j in seq_along(cols)) {
			trellis.focus("panel", cols[j], rows[i], highlight = FALSE)
			sppanel(sp.layout)
			trellis.unfocus()
		}
	}
}

#sp.pagefn = function(n) {
#	pos = lattice:::lattice.getStatus("current.panel.positions")
#	spplot.key(sp.layout, pos[1], pos[2])
#}

longlat.scales = function(obj, scales, xlim, ylim) {
	if (!is.null(scales$draw) && scales$draw &&
            !is.na(isp <- is.projected(obj)) && !isp) {
		# long lat -- x:
		if (is.null(scales$x))
			scales$x = list()
		if (is.null(scales$x$at))
			scales$x$at = pretty(xlim)
		if (is.null(scales$x$labels))
        	scales$x$labels = parse(text = degreeLabelsEW(scales$x$at))
		# long lat -- y:
		if (is.null(scales$y))
			scales$y = list()
		if (is.null(scales$y$at))
			scales$y$at = pretty(ylim)
		if (is.null(scales$y$labels))
        	scales$y$labels = parse(text = degreeLabelsNS(scales$y$at))
	}
	scales
}

bbexpand = function(x, fraction) {
	r = diff(x)
	c(x[1] - fraction * r, x[2] + fraction * r)
}

colorkey.factor = function(f, colorkey = list(), doColorkey = TRUE) {
	lf = levels(f)
	at = seq(0.5, nlevels(f)+0.501)
	at.labels = seq(1, nlevels(f))
	if (doColorkey) {
		colorkey=append(colorkey, list(labels=list(at=at.labels, labels=lf), 
			height=min(1, .05 * length(lf))))
		list(at = at, colorkey = colorkey)
	} else
		list(at = at)
}

"spplot.locator" <- function(n = 512, type = "n", ...) { 
	stopifnot(n > 0)
	res = as.numeric(grid.locator(unit = "native"))
	if (type == "o" || type == "p")
		panel.points(res[1], res[2], ...)
	if (n > 1) for (i in 2:n) {
		xy = grid.locator(unit = "native")
		if (is.null(xy))
			# return(res)
			break
		else
			xy = as.numeric(xy)
		res = rbind(res, xy)
		if (type == "o" || type == "p")
			panel.points(xy[1], xy[2], ...)
		if (type == "o" || type == "l")
			panel.lines(res[(i-1):i,])
	}
	if (is.matrix(res))
		dimnames(res) = list(NULL, NULL)
	res
}

addNAemptyRowsCols = function(obj) {
	# accept gridded; return SpatialPointsDataFrame with NA records on empty row/cols
	fullgrid(obj) = FALSE
	nfull = obj@grid@cells.dim[1] * obj@grid@cells.dim[2]
	missingpatt = rep(TRUE, nfull)
	missingpatt[obj@grid.index] = FALSE
	missingpatt = matrix(missingpatt,
		obj@grid@cells.dim[1], obj@grid@cells.dim[2], byrow = FALSE)
	missing.x = which(apply(missingpatt, 1, all))
	missing.y = which(apply(missingpatt, 2, all))

	xy = coordinates(obj)[,1:2,drop=FALSE]
	coordvals = coordinatevalues(obj@grid)
	missing.x = coordvals[[1]][missing.x]
	missing.y = coordvals[[2]][missing.y]
	n = length(missing.x) + length(missing.y)
	if (n > 0) {
		if (length(missing.x) > 0)
			xy = rbind(xy, cbind(missing.x, rep(xy[1,2], length(missing.x))))
		if (length(missing.y) > 0)
			xy = rbind(xy, cbind(rep(xy[1,1], length(missing.y)), missing.y))
		newatt = data.frame(lapply(obj@data, function(x) c(x, rep(NA, n))))
		row.names(xy) = seq_len(nrow(xy)) 
		obj = SpatialPointsDataFrame(xy, newatt, obj@coords.nrs, obj@proj4string, FALSE)
	} else
		obj = as(obj, "SpatialPointsDataFrame")
	obj
}

fill.call.groups <-
function (lst, z, ..., cuts = ifelse(identical(FALSE, colorkey), 5, 100), 
	#col.regions = trellis.par.get("regions")$col, 
    legendEntries = "", pch, cex = 1, do.fill = TRUE, do.log = FALSE, 
    key.space = ifelse(identical(FALSE, colorkey), "bottom", "right"), 
	cex.key, edge.col, colorkey) 
{
    dots = list(...)
	col.regions = lst$col.regions
    if (is.numeric(z)) {
        if (length(cuts) > 1) 
            ncuts = length(cuts) - 1
        else ncuts = cuts
        if (ncuts != length(col.regions)) {
            cols = round(1 + (length(col.regions) - 1) * (0:(ncuts - 
                1))/(ncuts - 1))
            fill = col.regions[cols]
        } else 
			fill = col.regions
        valid = !is.na(z)
        if (length(cuts) == 1) {
            if (do.log) {
                lz = log(z)
                cuts = c(min(z[valid]), exp(seq(min(lz[valid]), 
                  max(lz[valid]), length = cuts + 1))[2:(cuts)], 
                  max(z[valid]))
            }
            else cuts = seq(min(z[valid]), max(z[valid]), length.out = cuts +
                1)
        }
        groups = cut(as.matrix(z), cuts, dig.lab = 4, include.lowest = TRUE)
    } else if (is.factor(z)) {
        if (length(col.regions) == 1) 
            col.regions = rep(col.regions, nlevels(z))
        if (length(col.regions) < nlevels(z)) 
            stop("number of colors smaller than number of factor levels")
        if (length(col.regions) > nlevels(z)) {
            ncuts = nlevels(z)
            cols = round(1 + (length(col.regions) - 1) * (0:(ncuts - 
                1))/(ncuts - 1))
            col.regions = col.regions[cols]
        }
        if (!missing(cuts)) 
            stop("ncuts cannot be set for factor variable")
        groups = z
		fill = col.regions
    } else stop("dependent of not-supported class")
    n = nlevels(groups)

	# deal with col:
	lst$groups = fill[groups]
	#print(lst$col)

	# deal with pch:
	if (edge.col != "transparent") { # WITH border: use fill
    	if (missing(pch)) 
        	pch = rep(ifelse(do.fill, 21, 1), n)
		lst$col = rep(edge.col, length.out = length(groups))
	} else { # no border: use col instead of fill
    	if (missing(pch)) 
        	pch = rep(ifelse(do.fill, 16, 1), n)
		lst$col = lst$groups
	}

	if (length(pch) == 1)
		pch = rep(pch, n)
	lst$pch = pch[groups]

	# deal with cex:
	if (missing(cex))
		cex = rep(1, n)
	if (length(cex) == 1)
		cex = rep(cex, n)
	if (length(cex) == n) {
		cex.key = cex
		lst$cex = cex[groups]
		lst$cex[is.na(lst$cex)] = 0
	} else if (missing(cex.key))
		cex.key = mean(cex, na.rm = TRUE)

	# do key:
	if (is.list(colorkey))
		lst$legend = colorkey
	else if (isTRUE(colorkey)) {
		lst$legend = list(
			right = list(
				fun = draw.colorkey,
                args = list(
					key = list(
						col = col.regions, 
						at = cuts
					), 
                    draw = FALSE
				)
			)
		)
       	if (is.character(key.space)) 
			names(lst$legend) = key.space
	} else {
    	if (!identical(dots$auto.key, FALSE)) { # xxx
    		if (missing(legendEntries)) 
				legendEntries = levels(groups)
        	if (!is.null(dots$key)) 
            	lst$key = dots$key
			else { 
				if(is.list(dots$auto.key))
					lst$key = dots$auto.key
				else
					lst$key = list()
				if (edge.col != "transparent") {
					lst$key = append(lst$key,
						list(points = list(
							pch = rep(pch, length.out = n), 
							col = rep(edge.col, length.out = n), 
							fill = fill, 
							cex = rep(cex.key, length.out = n)
						), 
						text = list(legendEntries)
					))
				} else {
					lst$key = append(lst$key,
						list(points = list(
							pch = rep(pch, length.out = n), 
							col = rep(fill, length.out = n), 
							cex = rep(cex.key, length.out = n)
						), 
						text = list(legendEntries)
					))
				}
			}
        	if (is.character(key.space)) 
            	lst$key$space = key.space
        	else if (is.list(key.space)) 
            	lst$key = append(lst$key, key.space)
        	else warning("key.space argument ignored (not list or character)")
			# print(lst$key)
    	}
    	if (!is.null(dots$auto.key)) 
        	lst$auto.key <- dots$auto.key
	}
    return(lst)
}

panel.RgoogleMaps <- function(map) {
	bb = bb2merc(map, "RgoogleMaps")
	grid.raster(map$myTile, mean(bb[1,]), mean(bb[2,]), diff(bb[1,]), diff(bb[2,]), 
		default.units = "native", interpolate = FALSE)
}

panel.ggmap <- function(map) {
	bb = bb2merc(map, "ggmap")
	grid.raster(map, mean(bb[1,]), mean(bb[2,]), diff(bb[1,]), diff(bb[2,]), 
		default.units = "native", interpolate = FALSE)
}

Try the sp package in your browser

Any scripts or data that you put into this service are public.

sp documentation built on Nov. 27, 2023, 1:08 a.m.