diff --git a/DESCRIPTION b/DESCRIPTION index 1e91597..973ba39 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,14 +1,14 @@ Package: geoGraph Type: Package Title: Walking through the geographic space using graphs -Version: 1.1.1.9002 +Version: 1.1.1.9003 Authors@R: c( person("Thibaut", "Jombart", role = "aut"), person("Andrea", "Manica", email = "am315@cam.ac.uk", role = c("aut", "cre"))) Maintainer: Andrea Manica Description: Classes and methods for spatial graphs interfaced with support for GIS shapefiles. License: GPL (>=2) -Language: en-GB +Language: en-US URL: https://github.com/EvolEcolGroup/geograph, https://evolecolgroup.github.io/geograph/ BugReports: https://github.com/EvolEcolGroup/geograph/issues @@ -23,17 +23,16 @@ Depends: methods, graph Imports: - fields, - RBGL, - rnaturalearth, - rnaturalearthdata, - sp, - sf, - magrittr + fields, + RBGL, + rnaturalearth, + sf, + magrittr Suggests: testthat, knitr, - rmarkdown + rmarkdown, + rnaturalearthdata RoxygenNote: 7.2.3 Collate: 'classes.R' diff --git a/NAMESPACE b/NAMESPACE index ca52fd4..c9a3411 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -74,8 +74,9 @@ exportMethods(setDistCosts) exportMethods(setEdges) import(graph) import(methods) -import(sp) +import(sf) importFrom(graphics,identify) importFrom(graphics,locator) importFrom(graphics,segments) importFrom(magrittr,"%>%") +importFrom(rnaturalearth,ne_countries) diff --git a/NEWS.md b/NEWS.md index 9c84d13..ff02ec9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ # geoGraph (development version) -* +* remove all use of deprecated packages (`sp` and `maptools`), and move to + `sf` objects # geoGraph v1.1 diff --git a/R/buffer.R b/R/buffer.R index 4889b2a..40e94b8 100644 --- a/R/buffer.R +++ b/R/buffer.R @@ -12,7 +12,7 @@ #' @aliases buffer buffer-methods buffer,gGraph-method buffer,gData-method #' @param x a valid \linkS4class{gGraph} or \linkS4class{gData} object. #' @param \dots further arguments passed to specific methods. -#' @param nodes a character vector identifying the nodes aournd which buffers +#' @param nodes a character vector identifying the nodes around which buffers #' should be computed. #' @param d the radius of the buffer, in km. #' @param res.type the type of result that should be returned (see section diff --git a/R/combineCosts.R b/R/combineCosts.R index 777e2e5..cfeb5c3 100644 --- a/R/combineCosts.R +++ b/R/combineCosts.R @@ -1,7 +1,7 @@ #' Combine the costs of two gGraph objects #' #' The function \code{combineCosts} combines the edge costs of two -#' \linkS4class{gGraph} objects. The first object is used as a temlate to generate +#' \linkS4class{gGraph} objects. The first object is used as a template to generate #' the objects with the combined costs. Two two \linkS4class{gGraph} objects must #' have the same edges. #' @@ -20,7 +20,7 @@ #' the product or a custom function (defined in \code{FUN}) of the costs of its nodes. #' @param FUN a function used to compute the cost between two nodes (needed if \code{method="function"}). #' @param \dots additional parameters to be passed to \code{FUN}. -#' @return A \linkS4class{gGraph} object with the newly defined costs, basedd on the combination of the +#' @return A \linkS4class{gGraph} object with the newly defined costs, based on the combination of the #' two gGraph objects, used as weightings of edges. #' @export #' @examples diff --git a/R/connectivity.R b/R/connectivity.R index 548e5bc..88c1ede 100644 --- a/R/connectivity.R +++ b/R/connectivity.R @@ -50,7 +50,7 @@ #' #' - \code{isConnected}: a single logical value, being TRUE if nodes of the #' object form a connected set.\cr - +#' @include classes.R #' @keywords utilities methods #' @name connectivity #' @examples diff --git a/R/datasets.R b/R/datasets.R index 5736d6b..cd38528 100644 --- a/R/datasets.R +++ b/R/datasets.R @@ -17,7 +17,7 @@ #' @docType data #' @format \code{hgdp} is a \linkS4class{gGraph} object with the following #' data: % \describe{ % \item{@nodes.attr$habitat}{habitat corresponding to -#' each % vertice; currently 'land' or 'sea'.} % \item{@meta$color}{a matrix +#' each % vertex; currently 'land' or 'sea'.} % \item{@meta$color}{a matrix #' assigning a color for plotting % vertices (second column) to different #' values of habitat (first % column).} % } #' @references Authors \emph{Journal}, YEAR, \bold{nb}: pp-pp. @@ -70,24 +70,20 @@ NULL #' connectivity between edges at some places. The most noticeable change is that #' all edges involving sea vertices have been removed.\cr #' -#' 'worldshape' is a shapefile of countries of the world (snapshot from 1994). -#' -#' #' @name worldgraph #' @aliases worldgraph rawgraph.10k rawgraph.40k worldgraph.10k worldgraph.40k -#' worldshape #' @docType data #' @format \code{worldgraph.10k} and \code{worldgraph.40k} are #' \linkS4class{gGraph} objects with the following specificities: \describe{ -#' \item{@nodes.attr\$habitat}{habitat corresponding to each vertice; currently -#' 'land' or 'sea'.} \item{@meta\$color}{a matrix assigning a color for +#' \item{@nodes.attr$habitat}{habitat corresponding to each vertex; currently +#' 'land' or 'sea'.} \item{@meta$color}{a matrix assigning a color for #' plotting vertices (second column) to different values of habitat (first #' column).} } #' @references === On the construction of the graph ===\cr Randall, D. A.; #' Ringler, T. D.; Heikes, R. P.; Jones, P. & Baumgardner, J. Climate Modeling #' with Spherical Geodesic Grids \emph{Computing in science & engineering}, #' 2002, \bold{4}: 32-41. -#' @source Graph reconstructed by Andrea Manica. +#' @source Graph constructed by Andrea Manica. #' @keywords datasets #' @examples #' diff --git a/R/dijkstra.R b/R/dijkstra.R index 606f3e9..1b43990 100644 --- a/R/dijkstra.R +++ b/R/dijkstra.R @@ -364,7 +364,7 @@ plot.gPath <- function(x, col = "rainbow", lwd = 3, ...) { N <- length(vecNodes) if (N < 2) { return() - } # escape if a path is a single vertice + } # escape if a path is a single vertex from <- vecNodes[1:(N - 1)] to <- vecNodes[2:N] ## segments(xy[from,1], xy[from,2], xy[to,1], xy[to,2], col=col, lwd=lwd, ...) diff --git a/R/extractFromLayer.R b/R/extractFromLayer.R index 5ce28ae..4db0252 100644 --- a/R/extractFromLayer.R +++ b/R/extractFromLayer.R @@ -18,15 +18,13 @@ #' two columns giving longitudes and latitudes of locations being considered. #' For list, input must have two components being vectors giving longitudes and #' latitudes of locations. -#' @param layer a shapefile of the class \code{SpatialPolygonsDataFrame} (see -#' \code{readShapePoly} in maptools package to import such data from a GIS +#' @param layer a shapefile of the class [`sf`] (see +#' [sf::st_read()] to import a GIS #' shapefile). Alternatively, a character string indicating one shapefile -#' released with geoGraph; currently, only 'world' is available (see -#' \code{?data(worldshape)}). +#' released with geoGraph; currently, only 'world' is available. #' @param attr a character vector giving names of the variables to be extracted #' from the layer. If 'all', all available variables are extracted. In case of -#' problem, available names are displayed with the error message. Available -#' data are also stored in \code{layer@data}. +#' problem, available names are displayed with the error message. #' @param \dots further arguments to be passed to other methds. Currently not #' used. #' @return The output depends on the nature of the input:\cr - \code{matrix, @@ -51,13 +49,13 @@ #' #' ## retrieve continent info for all nodes #' ## (might take a few seconds) -#' x <- extractFromLayer(worldgraph.10k, layer = "world", attr = "CONTINENT") +#' x <- extractFromLayer(worldgraph.10k, layer = "world", attr = "continent") #' x -#' table(getNodesAttr(x, attr.name = "CONTINENT")) +#' table(getNodesAttr(x, attr.name = "continent")) #' #' #' ## subset Africa -#' temp <- getNodesAttr(x, attr.name = "CONTINENT") == "Africa" +#' temp <- getNodesAttr(x, attr.name = "continent") == "Africa" #' temp[is.na(temp)] <- FALSE #' x <- x[temp] #' plot(x, reset = TRUE) @@ -84,17 +82,13 @@ setGeneric("extractFromLayer", function(x, ...) { #' @rdname extractFromLayer #' @export setMethod("extractFromLayer", "matrix", function(x, layer = "world", attr = "all", ...) { - - - ## This functions automatically assigns to land all points overlapping the country polygons - # if(!require(maptools)) stop("maptools package is required.") ## Load default shapefile ## if (is.character(layer) && layer[1] == "world") { # use rnaturalearth instead of the inbuilt dataset - # layer <- rnaturalearth::ne_countries(scale="medium", returnclass = "sf") - # sf::sf_use_s2(FALSE) - layer <- sf::st_read(system.file("files/shapefiles/world-countries.shp", package = "geoGraph")) + layer <- rnaturalearth::ne_countries(scale="medium", returnclass = "sf") + sf::sf_use_s2(FALSE) + #layer <- sf::st_read(system.file("files/shapefiles/world-countries.shp", package = "geoGraph")) } ## TODO if the layer is null, we should throw an error!!! diff --git a/R/findLand.R b/R/findLand.R index bbbcca8..68195e4 100644 --- a/R/findLand.R +++ b/R/findLand.R @@ -13,11 +13,10 @@ #' @param x a matrix, a data.frame, or a valid \linkS4class{gGraph} object. For #' matrix and data.frame, input must have two columns giving longitudes and #' latitudes of locations being considered. -#' @param shape a shapefile of the class \code{SpatialPolygonsDataFrame} (see -#' \code{readShapePoly} in maptools package to import such data from a GIS +#' @param shape a shapefile of the class [`sf`] (see +#' [sf::st_read()] to import a GIS #' shapefile). Alternatively, a character string indicating one shapefile -#' released with geoGraph; currently, only 'world' is available (see -#' \code{?data(worldshape)}). +#' released with geoGraph; currently, only 'world' is available. #' @param \dots further arguments to be passed to other methods. Currently not #' used. #' @param attr.name a character string giving the name of the node attribute in @@ -49,7 +48,7 @@ #' ## define rules for colors #' temp <- data.frame(habitat = c("land", "sea"), color = c("green", "blue")) #' temp -#' obj@meta$color <- temp +#' obj@meta$colors <- temp #' #' ## plot object with new colors #' plot(obj) @@ -77,43 +76,42 @@ setGeneric("findLand", function(x, ...) { #' @rdname findLand #' @export setMethod("findLand", "matrix", function(x, shape = "world", ...) { - ## This functions automatically assigns to land all points overlapping the country polygons - # if(!require(maptools)) stop("maptools package is required.") - ## Load country shapefile + ## Load default shapefile ## if (is.character(shape) && shape[1] == "world") { - shape <- worldshape + # use rnaturalearth + shape <- rnaturalearth::ne_countries(scale="medium", returnclass = "sf") + sf::sf_use_s2(FALSE) } - if (!is.null(shape)) { # with background - if (!inherits(shape, "SpatialPolygonsDataFrame")) { - stop("Layer must be a SpatialPolygonsDataFrame object \n(see st_read and as_Spatial in sf to import such data from a GIS shapefile).") + + ## TODO if the shape is null, we should throw an error!!! + if (!is.null(shape)) { + if (!inherits(shape, "sf")) { + if (inherits(shape, "SpatialPolygonsDataFrame")){ + shape <- sf::st_as_sf(shape) + } else { + stop("shape must be a sf object \n(see st_read in sf to import such data from a GIS shapefile).") + } } } - + + if (any(is.na(x))) { stop("Matrix contains NA values.") } - - long <- x[, 1] - lat <- x[, 2] - n.country <- length(shape@polygons) - - ## create land vector to score land - land <- rep(0, length(lat)) - - for (i in 1:n.country) { - this.country <- shape@polygons[i][[1]] - n.polys <- length(this.country@Polygons) - - for (p in 1:n.polys) { - this.poly <- this.country@Polygons[p][[1]] - land <- land + point.in.polygon(long, lat, this.poly@coords[, 1], this.poly@coords[, 2]) - } - } - land[land > 1] <- 1 - land[land == 0] <- "sea" - land[land == 1] <- "land" + + # create an sf point object from the coordinates + locations_st <- x %>% as.data.frame %>% + sf::st_as_sf(coords=c(1,2)) %>% + sf::st_set_crs(sf::st_crs(shape)) + # now find points in polygons + points_within <- sf::st_intersects(shape, locations_st) + points_within <- data.frame(x = unlist(points_within), + polygon = rep(seq_along(lengths(points_within)), lengths(points_within))) + + land<-rep("sea",nrow(x)) + land[points_within$x]<-"land" return(factor(land)) }) diff --git a/R/geograph.R b/R/geograph.R index 63b553b..60453d6 100644 --- a/R/geograph.R +++ b/R/geograph.R @@ -45,7 +45,7 @@ #' #' - \code{\link{findLand}}: checks which nodes are on land.\cr #' -#' - \code{\link{setCosts}}: define edges weights accoring to rules specified +#' - \code{\link{setCosts}}: define edges weights according to rules specified #' in the @meta slot.\cr #' #' - \code{\link{geo.add.edges}}, \code{\link{geo.remove.edges}}: graphical @@ -83,14 +83,11 @@ #' since they provide the spatial models used in later operations. #' #' Two main datasets are proposed, each being a \linkS4class{gGraph} resulting -#' from the spliting of the earth into cells of (allmost perfectly) equal +#' from the spliting of the earth into cells of (almost perfectly) equal #' sizes. Two different resolutions are provided:\cr - #' \code{\link{worldgraph.10k}}: coverage using about 10,000 nodes\cr - #' \code{\link{worldgraph.40k}}: coverage using about 40,000 nodes\cr #' -#' Other datasets are:\cr - \code{\link{worldshape}}: shapefile containing -#' world countries.\cr -#' #' To cite geoGraph, please use the reference given by #' \code{citation("geoGraph")}. #' diff --git a/R/globals.R b/R/globals.R index 988f102..fb5044a 100644 --- a/R/globals.R +++ b/R/globals.R @@ -1 +1 @@ -utils::globalVariables(c("rawgraph.10k", "rawgraph.40k", "worldshape")) +utils::globalVariables(c("rawgraph.10k", "rawgraph.40k")) diff --git a/R/isInArea.R b/R/isInArea.R index 96f0560..2eed386 100644 --- a/R/isInArea.R +++ b/R/isInArea.R @@ -23,7 +23,7 @@ #' so \code{locator(1)} is a valid value for \code{reg}. #' @param res.type a character string indicating what kind of output should be #' produced. See value. -#' @param buffer a numeric value giving a buffer adding extra space aroung the +#' @param buffer a numeric value giving a buffer adding extra space around the #' area, as a proportion of current area's dimensions. #' @return The output depends on the value of the argument \code{res.type}:\cr #' - \code{logical}: a vector of logicals having one value for each node of the diff --git a/R/plot.R b/R/plot.R index bf2c565..eedc309 100644 --- a/R/plot.R +++ b/R/plot.R @@ -23,10 +23,10 @@ #' points,gGraph-method points.gGraph plotEdges #' @docType methods #' @param x a \linkS4class{gGraph} object. -#' @param shape a shapefile used as background to the object. Must be of the -#' class \code{SpatialPolygonsDataFrame} (see \code{readShapePoly} in maptools -#' package to import such data from a GIS shapefile). Alternatively, a -#' character string indicating one shapefile released with geoGraph. +#' @param shape a shapefile of the class [`sf`] (see +#' [sf::st_read()] to import a GIS +#' shapefile). Alternatively, a character string indicating one shapefile +#' released with geoGraph; currently, only 'world' is available. #' @param psize a numeric giving the size of points. #' @param pch a numeric or a character indicating the type of point. #' @param col a character string indicating the color to be used. @@ -64,6 +64,7 @@ #' #' - \code{\link{isInArea}}, to retain a set of visible data.\cr #' @keywords methods hplot spatial +#' @importFrom rnaturalearth ne_countries #' @examples #' #' @@ -103,7 +104,7 @@ NULL ## plot for gGraph ################### #' @export -#' @import sp +#' @import sf setMethod("plot", signature(x = "gGraph", y = "missing"), function(x, y, shape = "world", psize = NULL, pch = 19, col = NULL, edges = FALSE, reset = FALSE, bg.col = "gray", border.col = "dark gray", lwd = 1, useCosts = NULL, maxLwd = 3, col.rules = NULL, ...) { @@ -191,16 +192,23 @@ setMethod("plot", signature(x = "gGraph", y = "missing"), function(x, y, shape = ## handle shape if (!is.null(shape) && is.character(shape) && shape == "world") { - shape <- worldshape - } - - if (!is.null(shape)) { ## plot with background ## - if (!inherits(shape, "SpatialPolygonsDataFrame")) { - stop("Layer must be a SpatialPolygonsDataFrame object \n(see st_read and as_Spatial in sf to import such data from a GIS shapefile).") + #shape <- sf::st_read(system.file("files/shapefiles/world-countries.shp", package = "geoGraph")) + shape <- rnaturalearth::ne_countries(scale="medium", returnclass = "sf") + sf::sf_use_s2(FALSE) + } + + ## TODO if the shape is null, we should throw an error!!! + if (!is.null(shape)) { + if (!inherits(shape, "sf")) { + if (inherits(shape, "SpatialPolygonsDataFrame")){ + shape <- sf::st_as_sf(shape) + } else { + stop("shape must be a sf object \n(see st_read in sf to import such data from a GIS shapefile).") + } } ## plot background - plot(shape, col = bg.col, border = border.col, xlim = xlim, ylim = ylim) + plot(sf::st_geometry(shape), col = bg.col, border = border.col, xlim = xlim, ylim = ylim) ## subset of points in area toKeep <- isInArea(x, reg = "current", res.type = "character") diff --git a/README.md b/README.md index b3eee41..2ed089b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ `geoGraph` aims at implementing graph approaches for geographic data. -In `geoGraph`, a given geographic area is modelled by a fine regular grid, where each vertice +In `geoGraph`, a given geographic area is modelled by a fine regular grid, where each vertex has a set of spatial coordinates and a set of attributes, which can be for instance habitat descriptors, or the presence/abundance of a given species. 'Travelling' within the geographic area can then be easily modelled as moving between connected vertices. diff --git a/data/worldshape.rda b/data-raw/worldshape.rda similarity index 100% rename from data/worldshape.rda rename to data-raw/worldshape.rda diff --git a/inst/files/shapefiles/world-countries.dbf b/inst/files/shapefiles/world-countries.dbf deleted file mode 100644 index 6acffe5..0000000 Binary files a/inst/files/shapefiles/world-countries.dbf and /dev/null differ diff --git a/inst/files/shapefiles/world-countries.sbn b/inst/files/shapefiles/world-countries.sbn deleted file mode 100644 index f12623f..0000000 Binary files a/inst/files/shapefiles/world-countries.sbn and /dev/null differ diff --git a/inst/files/shapefiles/world-countries.sbx b/inst/files/shapefiles/world-countries.sbx deleted file mode 100644 index e6da600..0000000 Binary files a/inst/files/shapefiles/world-countries.sbx and /dev/null differ diff --git a/inst/files/shapefiles/world-countries.shp b/inst/files/shapefiles/world-countries.shp deleted file mode 100644 index 797d667..0000000 Binary files a/inst/files/shapefiles/world-countries.shp and /dev/null differ diff --git a/inst/files/shapefiles/world-countries.shx b/inst/files/shapefiles/world-countries.shx deleted file mode 100644 index ab39ac5..0000000 Binary files a/inst/files/shapefiles/world-countries.shx and /dev/null differ diff --git a/man/buffer.Rd b/man/buffer.Rd index 5dd8014..caeeec2 100644 --- a/man/buffer.Rd +++ b/man/buffer.Rd @@ -14,7 +14,7 @@ \arguments{ \item{x}{a valid \linkS4class{gGraph} or \linkS4class{gData} object.} -\item{nodes}{a character vector identifying the nodes aournd which buffers +\item{nodes}{a character vector identifying the nodes around which buffers should be computed.} \item{d}{the radius of the buffer, in km.} diff --git a/man/combineCosts.Rd b/man/combineCosts.Rd index 2245086..1d4646e 100644 --- a/man/combineCosts.Rd +++ b/man/combineCosts.Rd @@ -21,12 +21,12 @@ the product or a custom function (defined in \code{FUN}) of the costs of its nod \item{\dots}{additional parameters to be passed to \code{FUN}.} } \value{ -A \linkS4class{gGraph} object with the newly defined costs, basedd on the combination of the +A \linkS4class{gGraph} object with the newly defined costs, based on the combination of the two gGraph objects, used as weightings of edges. } \description{ The function \code{combineCosts} combines the edge costs of two -\linkS4class{gGraph} objects. The first object is used as a temlate to generate +\linkS4class{gGraph} objects. The first object is used as a template to generate the objects with the combined costs. Two two \linkS4class{gGraph} objects must have the same edges. } diff --git a/man/extractFromLayer.Rd b/man/extractFromLayer.Rd index 6947de3..2607f3d 100644 --- a/man/extractFromLayer.Rd +++ b/man/extractFromLayer.Rd @@ -32,16 +32,14 @@ latitudes of locations.} \item{\dots}{further arguments to be passed to other methds. Currently not used.} -\item{layer}{a shapefile of the class \code{SpatialPolygonsDataFrame} (see -\code{readShapePoly} in maptools package to import such data from a GIS +\item{layer}{a shapefile of the class \code{\link{sf}} (see +\code{\link[sf:st_read]{sf::st_read()}} to import a GIS shapefile). Alternatively, a character string indicating one shapefile -released with geoGraph; currently, only 'world' is available (see -\code{?data(worldshape)}).} +released with geoGraph; currently, only 'world' is available.} \item{attr}{a character vector giving names of the variables to be extracted from the layer. If 'all', all available variables are extracted. In case of -problem, available names are displayed with the error message. Available -data are also stored in \code{layer@data}.} +problem, available names are displayed with the error message.} } \value{ The output depends on the nature of the input:\cr - \code{matrix, @@ -73,13 +71,13 @@ plot(worldgraph.10k, reset = TRUE) ## retrieve continent info for all nodes ## (might take a few seconds) -x <- extractFromLayer(worldgraph.10k, layer = "world", attr = "CONTINENT") +x <- extractFromLayer(worldgraph.10k, layer = "world", attr = "continent") x -table(getNodesAttr(x, attr.name = "CONTINENT")) +table(getNodesAttr(x, attr.name = "continent")) ## subset Africa -temp <- getNodesAttr(x, attr.name = "CONTINENT") == "Africa" +temp <- getNodesAttr(x, attr.name = "continent") == "Africa" temp[is.na(temp)] <- FALSE x <- x[temp] plot(x, reset = TRUE) diff --git a/man/findLand.Rd b/man/findLand.Rd index f84d0a7..8ee3c69 100644 --- a/man/findLand.Rd +++ b/man/findLand.Rd @@ -24,11 +24,10 @@ latitudes of locations being considered.} \item{\dots}{further arguments to be passed to other methods. Currently not used.} -\item{shape}{a shapefile of the class \code{SpatialPolygonsDataFrame} (see -\code{readShapePoly} in maptools package to import such data from a GIS +\item{shape}{a shapefile of the class \code{\link{sf}} (see +\code{\link[sf:st_read]{sf::st_read()}} to import a GIS shapefile). Alternatively, a character string indicating one shapefile -released with geoGraph; currently, only 'world' is available (see -\code{?data(worldshape)}).} +released with geoGraph; currently, only 'world' is available.} \item{attr.name}{a character string giving the name of the node attribute in which the output is to be stored.} @@ -67,7 +66,7 @@ obj # note: new node attribute ## define rules for colors temp <- data.frame(habitat = c("land", "sea"), color = c("green", "blue")) temp -obj@meta$color <- temp +obj@meta$colors <- temp ## plot object with new colors plot(obj) diff --git a/man/geoGraph-package.Rd b/man/geoGraph-package.Rd index 3b888b3..a658d41 100644 --- a/man/geoGraph-package.Rd +++ b/man/geoGraph-package.Rd @@ -40,7 +40,7 @@ instance, to find the closest node on land.\cr \item \code{\link{show}}: printing of gGraph objects.\cr \item \code{\link{extractFromLayer}}: extract information from GIS layers.\cr \item \code{\link{findLand}}: checks which nodes are on land.\cr -\item \code{\link{setCosts}}: define edges weights accoring to rules specified +\item \code{\link{setCosts}}: define edges weights according to rules specified in the @meta slot.\cr \item \code{\link{geo.add.edges}}, \code{\link{geo.remove.edges}}: graphical functions for adding or removing edges.\cr @@ -72,14 +72,11 @@ bookmarked area.\cr since they provide the spatial models used in later operations. Two main datasets are proposed, each being a \linkS4class{gGraph} resulting -from the spliting of the earth into cells of (allmost perfectly) equal +from the spliting of the earth into cells of (almost perfectly) equal sizes. Two different resolutions are provided:\cr - \code{\link{worldgraph.10k}}: coverage using about 10,000 nodes\cr - \code{\link{worldgraph.40k}}: coverage using about 40,000 nodes\cr -Other datasets are:\cr - \code{\link{worldshape}}: shapefile containing -world countries.\cr - To cite geoGraph, please use the reference given by \code{citation("geoGraph")}. } diff --git a/man/hgdp.Rd b/man/hgdp.Rd index 32341f9..3cab984 100644 --- a/man/hgdp.Rd +++ b/man/hgdp.Rd @@ -8,7 +8,7 @@ \format{ \code{hgdp} is a \linkS4class{gGraph} object with the following data: \% \describe{ \% \item{@nodes.attr$habitat}{habitat corresponding to -each \% vertice; currently 'land' or 'sea'.} \% \item{@meta$color}{a matrix +each \% vertex; currently 'land' or 'sea'.} \% \item{@meta$color}{a matrix assigning a color for plotting \% vertices (second column) to different values of habitat (first \% column).} \% } } diff --git a/man/isInArea.Rd b/man/isInArea.Rd index 2f13b5c..7f127bb 100644 --- a/man/isInArea.Rd +++ b/man/isInArea.Rd @@ -56,7 +56,7 @@ so \code{locator(1)} is a valid value for \code{reg}.} \item{res.type}{a character string indicating what kind of output should be produced. See value.} -\item{buffer}{a numeric value giving a buffer adding extra space aroung the +\item{buffer}{a numeric value giving a buffer adding extra space around the area, as a proportion of current area's dimensions.} } \value{ diff --git a/man/plot-gGraph.Rd b/man/plot-gGraph.Rd index 12ddaa7..9bd7620 100644 --- a/man/plot-gGraph.Rd +++ b/man/plot-gGraph.Rd @@ -13,10 +13,10 @@ \arguments{ \item{x}{a \linkS4class{gGraph} object.} -\item{shape}{a shapefile used as background to the object. Must be of the -class \code{SpatialPolygonsDataFrame} (see \code{readShapePoly} in maptools -package to import such data from a GIS shapefile). Alternatively, a -character string indicating one shapefile released with geoGraph.} +\item{shape}{a shapefile of the class \code{\link{sf}} (see +\code{\link[sf:st_read]{sf::st_read()}} to import a GIS +shapefile). Alternatively, a character string indicating one shapefile +released with geoGraph; currently, only 'world' is available.} \item{psize}{a numeric giving the size of points.} diff --git a/man/worldgraph.Rd b/man/worldgraph.Rd index 4ae5fc9..4a59995 100644 --- a/man/worldgraph.Rd +++ b/man/worldgraph.Rd @@ -7,18 +7,17 @@ \alias{rawgraph.40k} \alias{worldgraph.10k} \alias{worldgraph.40k} -\alias{worldshape} \title{Worldwide geographic graphs} \format{ \code{worldgraph.10k} and \code{worldgraph.40k} are \linkS4class{gGraph} objects with the following specificities: \describe{ -\item{@nodes.attr\$habitat}{habitat corresponding to each vertice; currently -'land' or 'sea'.} \item{@meta\$color}{a matrix assigning a color for +\item{@nodes.attr$habitat}{habitat corresponding to each vertex; currently +'land' or 'sea'.} \item{@meta$color}{a matrix assigning a color for plotting vertices (second column) to different values of habitat (first column).} } } \source{ -Graph reconstructed by Andrea Manica. +Graph constructed by Andrea Manica. } \description{ The datasets 'rawgraph.10k', 'rawgraph.40k', 'worldgraph.10k', and @@ -32,8 +31,6 @@ references.\cr 'worldgraph's are 'rawgraph's that have been modified manually to rectify connectivity between edges at some places. The most noticeable change is that all edges involving sea vertices have been removed.\cr - -'worldshape' is a shapefile of countries of the world (snapshot from 1994). } \examples{ diff --git a/tests/testthat/test_extractFromLayer.R b/tests/testthat/test_extractFromLayer.R index b0cad72..035521d 100644 --- a/tests/testthat/test_extractFromLayer.R +++ b/tests/testthat/test_extractFromLayer.R @@ -3,6 +3,6 @@ test_that("extractFromLayer assigns points correctly", # create a matrix of locations including two continents and the sea myCoords <- data.frame(long = c(-24, 71.5, -46.5), lat = c(31, 30,-23.5)) # assign to continents - continents <- extractFromLayer(myCoords, layer = worldshape, attr = "CONTINENT") - expect_identical(as.character(continents$CONTINENT), c(NA,"Asia","South America")) + continents <- extractFromLayer(myCoords, layer = "world", attr = "continent") + expect_identical(as.character(continents$continent), c(NA,"Asia","South America")) }) \ No newline at end of file diff --git a/tests/testthat/test_findLand.R b/tests/testthat/test_findLand.R index 17af0be..ec53c4c 100644 --- a/tests/testthat/test_findLand.R +++ b/tests/testthat/test_findLand.R @@ -28,7 +28,7 @@ test_that("co-ordinate format",{ obj <- findLand(obj) #check for factor output - expect_is(obj,"factor") + expect_true(inherits(obj,"factor")) #check for correct output expect_equal(obj,factor(c('sea','land'))) diff --git a/tests/testthat/test_setCosts.R b/tests/testthat/test_setCosts.R index aab4e82..d26fb37 100644 --- a/tests/testthat/test_setCosts.R +++ b/tests/testthat/test_setCosts.R @@ -1,5 +1,4 @@ library("geoGraph") -context("test cost setting") test_that("arbitrary function to set costs", { data("worldgraph.40k") diff --git a/vignettes/geograph.Rmd b/vignettes/geograph.Rmd index 7e0577d..878d5d4 100644 --- a/vignettes/geograph.Rmd +++ b/vignettes/geograph.Rmd @@ -466,10 +466,6 @@ geo.zoomin(c(110, 130, -27, -12)) geo.bookmark("australia") ``` - - - - ### Changing local properties of a `gGraph` A second approach to changing a `gGraph` is to refine the graph by hand, adding or removing @@ -500,9 +496,6 @@ reference can be added to the current `gGraph`. For graphs based on 10k or 40k grids, the raw graphs provided in `geoGraph` should be used, (`rawgraph.10k`, `rawgraph.40k`), since they are fully connected. - - - In addition to changing grid connectivity, we may also want to modify the attributes of specific nodes. This is again done interactively, using the function `geo.change.attr`. For instance, here, we define a new value `shalowwater` (plotted in light blue) for the attribute `habitat`, @@ -525,56 +518,51 @@ plot(newGraph, edge = TRUE) Again, note that the changes made to the graph have to be save in an object (using `<-`) to be effective. - - - - - - ## Extracting information from GIS shapefiles An important feature of *geoGraph* is serving as an interface between *geographic information system* (GIS) layers and geographic data. As currently implemented, *geoGraph* can extract information from shapefiles with the Arc GIS (http://www.esri.com/software/arcgis/index.html) format, using the function `extractFromLayer`. -Here, we illustrate this procedure using the shapefile `world-countries.shp` provided with the -package. *geoGraph* still relies on `SpatialPolygonDataFrame` objects from the `sp` package. -A move to `sf` objects is planned, but for the moment we have to use `sf::st_read()` to read -a GIS shapefile into an `sf` object, and then cast it to a `SpatialPolygonDataFrame` with -`sf::as_Spatial()`: +Here, we illustrate this procedure using the `ne_countries` datasets from `rnaturalearth`, but +it is possible also to load custom GIS shapefilew with `sf::st_read()`. Note that we +turn off spherical trigonometry functions, as the naturalearth dataset is not compatible +with that functionality. ```{r } library(sf) -world.countries <- sf::st_read(system.file("files/shapefiles/world-countries.shp", package = "geoGraph")) -world.countries <- sf::as_Spatial(world.countries) +world.countries <- rnaturalearth::ne_countries(scale="medium", returnclass = "sf") +sf::sf_use_s2(FALSE) + class(world.countries) summary(world.countries) ``` + The summary of `world.countries` shows the data (attributes) stored in the layer. Let us assume that we are interested in retrieving continent and country information for the `worldgraph.10k` object. Note that `extractFromLayer` can extract information to other types of objects than `gGraph` (see `?extractFromLayer`) ```{r } summary(getNodesAttr(worldgraph.10k)) -newGraph <- extractFromLayer(worldgraph.10k, layer = world.countries, attr = c("CONTINENT", "NAME")) +newGraph <- extractFromLayer(worldgraph.10k, layer = world.countries, attr = c("continent", "name")) summary(getNodesAttr(newGraph)) ``` + The new object `newGraph` is a `gGraph` which now includes, for each node of the grid, the corresponding continent and country retrieved from the GIS layer. We can use the newly acquired information for plotting `newGraph`, by defining new color rules: ```{r fig=TRUE} -temp <- unique(getNodesAttr(newGraph)$"NAME") +temp <- unique(getNodesAttr(newGraph)$"name") col <- c("transparent", rainbow(length(temp) - 1)) -colMat <- data.frame(NAME = temp, color = col) +colMat <- data.frame(name = temp, color = col) head(colMat) tail(colMat) plot(newGraph, col.rules = colMat, reset = TRUE) ``` - This information could in turn be used to define costs for travelling on the grid. +This information could in turn be used to define costs for travelling on the grid. For instance, one could import habitat descriptors from a GIS, use these values to formulate a habitat model, and derive costs for dispersal on the grid. - As soon as a GIS layer has been extracted to a `gGraph`, this information becomes also available for any `gData` interfaced with this object. For instance, we can re-use the `cities` example defined in a previous section, and interface it @@ -587,12 +575,6 @@ getData(cities) getNodesAttr(cities) ``` - - - - - - ## Finding least-cost paths One of the most useful applications of *geoGraph* is the research of least-cost paths between @@ -615,10 +597,9 @@ plot(hgdp, reset = TRUE) pink: coasts). Population genetics predicts that genetic diversity within populations should decay as populations are located further away from the geographic origin of the species. -Here, we verify this relationship for a theoretical origin in Addis abeba, Ethiopia. +Here, we verify this relationship for a theoretical origin in Addis Ababa, Ethiopia. We shall seek all paths through landmasses to the HGDP populations. - First, we check that all populations are connected on the grid using `isConnected`: ```{r } isConnected(hgdp) @@ -636,7 +617,6 @@ geo.zoomin(c(90, 150, 18, -25)) title("Different connected components\n in worldgraph.10k") ``` - Since all locations in `hgdp` are connected, we can proceed further. We have to set the costs of edges in the `gGraph` grid. To do so, we can choose between i) strictly uniform costs (using `dropCosts`) ii) @@ -646,7 +626,7 @@ costs (using `setCosts`). We shall first illustrate the strictly uniform costs. After setting a `gGraph` with uniform costs, we use `dijkstraFrom` to find the shortest -paths between Addis abeba and the populations of `hgdp`: +paths between Addis Ababa and the populations of `hgdp`: ```{r } myGraph <- dropCosts(worldgraph.40k) hgdp@gGraph.name <- "myGraph" @@ -661,7 +641,7 @@ addis <- as.vector(addis) plot(myGraph, col = NA, reset = TRUE) plot(paths) points(addis[1], addis[2], pch = "x", cex = 2) -text(addis[1] + 35, addis[2], "Addis abeba", cex = .8, font = 2) +text(addis[1] + 35, addis[2], "Addis Ababa", cex = .8, font = 2) points(hgdp, col.node = "black") ``` @@ -678,7 +658,6 @@ summary(lm.unif) title("Genetic diversity vs geographic distance \n uniform costs ") ``` - Alternatively, we can use costs based on habitat. As a toy example, we will consider that coasts are four times more favourable for dispersal than the rest of the landmasses. @@ -693,7 +672,7 @@ paths.2 <- dijkstraFrom(hgdp, ori) plot(newGraph, col = NA, reset = TRUE) plot(paths.2) points(addis[1], addis[2], pch = "x", cex = 2) -text(addis[1] + 35, addis[2], "Addis abeba", cex = .8, font = 2) +text(addis[1] + 35, addis[2], "Addis Ababa", cex = .8, font = 2) points(hgdp, col.node = "black") ``` @@ -710,4 +689,3 @@ title("Genetic diversity vs geographic distance \n habitat costs ") Of course, the distinction between coasts and inner landmasses is a somewhat poor description of habitat. In practice, complex habitat models can be used as simply. -