diff --git a/R/recmap.R b/R/recmap.R index 2b3b7cb..9b8cba4 100644 --- a/R/recmap.R +++ b/R/recmap.R @@ -422,7 +422,7 @@ as.recmap.SpatialPolygonsDataFrame <- function(X){ #' #' @inheritParams base::summary #' -#' @references \doi{10.1109/TVCG.2004.1260761} +#' @inherit recmap references author #' #' @return #' returns a \code{data.frame} containing summary information, e.g., @@ -493,6 +493,7 @@ summary.recmap <- function(object, ...) { #' @param col.text a vector of colors. #' @param \ldots whatsoever #' +#' @inherit recmap references author #' @return graphical output #' #' @exportS3Method plot recmap diff --git a/src/Recmap.cpp b/src/Recmap.cpp index c4b5909..1a0d02c 100644 --- a/src/Recmap.cpp +++ b/src/Recmap.cpp @@ -57,55 +57,50 @@ DataFrame place_rectangle(double x0, double y0, double dx0, double dy0, //' @description //' The input consists of a map represented by overlapping rectangles. //' The algorithm requires as input for each map region: -//' \itemize{ -//' \item{a tuple of (x, y) values corresponding to the -//' (longitude, latitude) position,} -//' \item{a tuple of (dx, dy) of expansion along (longitude, latitude),} -//' \item{and a statistical value z.} -//' } -//' The (x, y) coordinates represent the center of the minimal bounding boxes -//' (MBB), The coordinates of the MBB are derived by adding or subtracting the -//' (dx, dy) / 2 tuple accordingly. The tuple (dx, dy) also defines the ratio of the +//' * a tuple of (x, y) values corresponding to the +//' (longitude, latitude) position, +//' * a tuple of (dx, dy) of expansion along (longitude, latitude), +//' * and a statistical value z. +//' +//' The (x, y) coordinates represent the center of the minimal bounding boxes +//' (MBB), The coordinates of the MBB are derived by adding or subtracting the +//' (dx, dy) / 2 tuple accordingly. The tuple (dx, dy) also defines the ratio of the //' map region. The statistical values define the desired area of each map region. //' //' The output is a rectangular cartogram where the map regions are: //' -//' \itemize{ -//' \item{Non-overlapping,} -//' \item{connected,} -//' \item{ratio and area of each rectangle correspond to the desired areas,} -//' \item{rectangles are placed parallel to the axes.} -//' } +//' * Non-overlapping, +//' * connected, +//' * ratio and area of each rectangle correspond to the desired areas, +//' * rectangles are placed parallel to the axes. //' -//' The construction heuristic places each rectangle in a way that important spatial +//' The construction heuristic places each rectangle in a way that important spatial //' constraints, in particular -//' \itemize{ -//' \item{the topology of the pseudo dual graph,} -//' \item{the relative position of MBB centers.} -//' } +//' * the topology of the pseudo dual graph, +//' * the relative position of MBB centers. +//' //' are tried to be preserved. //' -//' The ratios are preserved and the area of each region corresponds to the as +//' The ratios are preserved and the area of each region corresponds to the as //' input given statistical value z. //' //' @param V defines the input map regions formatted as \code{\link{data.frame}} -//' having the column names \code{c('x', 'y', 'dx', 'dy', 'z', 'name')} +//' having the column names \code{c('x', 'y', 'dx', 'dy', 'z', 'name')} //' as described above. V could also be considered as the nodes of the pseudo dual. //' -//' @param E defines the edges of the map region's pseudo dual graph. +//' @param E defines the edges of the map region's pseudo dual graph. //' If \code{E} is not provided, this is the default; the pseudo dual graph is //' composed of overlapping rectangles. If used, E must be a //' \code{\link{data.frame}} containing two columns named \code{c('u', 'v')} //' of type integer referencing the row number of \code{V}. //' //' @details The basic idea of the current recmap \emph{implementation}: -//' \enumerate{ -//' \item{Compute the pseudo dual out of the overlapping map regions.} -//' \item{Determine the \emph{core region} by \code{index <- int(n / 2)}.} -//' \item{Place region by region along DFS skeleton of pseudo dual starting -//' with the \emph{core region}.}} +//' 1. Compute the pseudo dual out of the overlapping map regions. +//' 2. Determine the \emph{core region} by \code{index <- int(n / 2)}. +//' 3. Place region by region along DFS skeleton of pseudo dual starting +//' with the \emph{core region}. //' -//' Note: if a rectangle can not be placed, accept a non-\emph{feasible solution} +//' @note if a rectangle can not be placed, accept a non-\emph{feasible solution} //' (avoid solutions having a topology error higher than 100) //' Solving this constellation can be intensive in the computation, and due to the //' assumably low fitness value the candidate cartogram @@ -113,27 +108,27 @@ DataFrame place_rectangle(double x0, double y0, double dx0, double dy0, //' //' \emph{Time Complexity:} //' The time complexity is \eqn{O(n^2)}, where n is the number of regions. -//' DFS is visiting each map region only once and therefore has +//' DFS is visiting each map region only once and therefore has //' time complexity \eqn{O(n)}. For each placement, a constant number of //' MBB intersection are called (max 360). MBB check is implemented using -//' \code{std::set}, \code{insert}, \code{upper_bound}, \code{upper_bound} +//' \code{std::set}, \code{insert}, \code{upper_bound}, \code{upper_bound} //' costs are \eqn{O(\log(n))}{O(log(n))}. //' However, the worst case for a range query is \eqn{O(n)}, if and only if dx or dy //' cover the whole x or y range. Q.E.D. -//' +//' //' \emph{Performance:} -//' In praxis, computing on a 2.4 GHz Intel Core i7 machine (using only one core), using the +//' In praxis, computing on a 2.4 GHz Intel Core i7 machine (using only one core), using the //' 50 state U.S. map example, recmap can compute approximately 100 cartograms in one second. //' The number of MBB calls were //' (Min., Median, Mean, Max) = (1448, 2534, 3174, 17740), using in each run //' a different index order using the (\code{\link{sample}}) method. -//' -//' \emph{Geodetic datum:} the \code{recmap} algorithm is not transforming the +//' +//' \emph{Geodetic datum:} the \code{recmap} algorithm is not transforming the //' geodetic datum, e.g., WGS84 or Swissgrid. -//' +//' //' @return -//' Returns a \code{recmap} S3 object of the transformed map with new coordinates -//' (x, y, dx, dy) plus additional columns containing information for topology +//' Returns a \code{recmap} S3 object of the transformed map with new coordinates +//' (x, y, dx, dy) plus additional columns containing information for topology //' error, relative position error, and the DFS number. //' The error values are thought to be used for fitness function of the //' metaheuristic. @@ -141,18 +136,21 @@ DataFrame place_rectangle(double x0, double y0, double dx0, double dy0, //' @aliases RecMap cartogram all.equal.recmap //' //' @author Christian Panse, 2016 -//' +//' @references +//' * \doi{10.18637/jss.v086.c01} +//' * \doi{10.1109/INFVIS.2004.57} +//' //' @examples //' map <- checkerboard(2) //' cartogram <- recmap(map) -//' +//' //' map //' cartogram -//' +//' //' op <- par(mfrow = c(1, 2)) //' plot(map) //' plot(cartogram) -//' +//' //' ## US example //' usa <- data.frame(x = state.center$x, //' y = state.center$y, @@ -163,15 +161,15 @@ DataFrame place_rectangle(double x0, double y0, double dx0, double dy0, //' dy = sqrt(state.area) / 2 / (0.8 * 60), //' z = sqrt(state.area), //' name = state.name) -//' +//' //' usa$z <- state.x77[, 'Population'] //' US.Map <- usa[match(usa$name, //' c('Hawaii', 'Alaska'), nomatch = 0) == 0, ] -//' +//' //' plot.recmap(US.Map) //' US.Map |> recmap() |> plot() //' par(op) -//' +//' //' # define a fitness function //' recmap.fitness <- function(idxOrder, Map, ...){ //' Cartogram <- recmap(Map[idxOrder, ]) @@ -183,6 +181,7 @@ DataFrame place_rectangle(double x0, double y0, double dx0, double dy0, //' } //' //' @export +//' @md // [[Rcpp::export]] DataFrame recmap(DataFrame V, Rcpp::Nullable E = R_NilValue) { // access the columns @@ -204,7 +203,7 @@ DataFrame recmap(DataFrame V, Rcpp::Nullable E = R_NilValue) { u = pd("u"); v = pd("v"); } - + NumericVector cartogram_x(x.size()); NumericVector cartogram_y(x.size()); @@ -234,8 +233,8 @@ DataFrame recmap(DataFrame V, Rcpp::Nullable E = R_NilValue) { }else{ X.run(true); } - - + + // Rcpp::Rcout << "Number of mbb intersection test calls = " // << X.get_intersect_count() << "\n"; for (int i = 0; i < x.size(); i++) {