diff --git a/DESCRIPTION b/DESCRIPTION index 12c8200..52dc11c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: spatstat.geom -Version: 3.2-9.021 -Date: 2024-06-15 +Version: 3.2-9.022 +Date: 2024-06-16 Title: Geometrical Functionality of the 'spatstat' Family Authors@R: c(person("Adrian", "Baddeley", role = c("aut", "cre", "cph"), diff --git a/NAMESPACE b/NAMESPACE index 3bfd364..e5746d1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -29,6 +29,7 @@ export("acedist.noshow") export("acedist.show") export("add.texture") export("affine") +export("affine.diagramobj") export("affine.distfun") export("affine.im") export("affine.layered") @@ -382,6 +383,7 @@ export("fft2D") export("fftwAvailable") export("fillNA") export("flipxy") +export("flipxy.diagramobj") export("flipxy.distfun") export("flipxy.im") export("flipxy.infline") @@ -855,13 +857,13 @@ export("rebound.im") export("rebound.owin") export("rebound.ppp") export("rebound.psp") -export("recognise.spatstat.type") export("rectdistmap") export("rectquadrat.breaks") export("rectquadrat.countEngine") export("redraw.simplepanel") export("reflect") export("reflect.default") +export("reflect.diagramobj") export("reflect.distfun") export("reflect.im") export("reflect.infline") @@ -900,6 +902,7 @@ export("rjitter") export("rjitter.ppp") export("rlinegrid") export("rotate") +export("rotate.diagramobj") export("rotate.distfun") export("rotate.im") export("rotate.infline") @@ -1208,6 +1211,7 @@ S3method("Summary", "imlist") # Automatically generated list of S3 methods # ......................................... S3method("$", "hyperframe") +S3method("affine", "diagramobj") S3method("affine", "distfun") S3method("affine", "im") S3method("affine", "layered") @@ -1385,6 +1389,7 @@ S3method("eroded.volumes", "boxx") S3method("erosion", "psp") S3method("fardist", "owin") S3method("fardist", "ppp") +S3method("flipxy", "diagramobj") S3method("flipxy", "distfun") S3method("flipxy", "im") S3method("flipxy", "infline") @@ -1594,6 +1599,7 @@ S3method("rebound", "owin") S3method("rebound", "ppp") S3method("rebound", "psp") S3method("reflect", "default") +S3method("reflect", "diagramobj") S3method("reflect", "distfun") S3method("reflect", "im") S3method("reflect", "infline") @@ -1611,6 +1617,7 @@ S3method("rescale", "distfun") S3method("rescale", "unitname") S3method("rexplode", "ppp") S3method("rjitter", "ppp") +S3method("rotate", "diagramobj") S3method("rotate", "distfun") S3method("rotate", "im") S3method("rotate", "infline") diff --git a/NEWS b/NEWS index 409a57b..db1814e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ - CHANGES IN spatstat.geom VERSION 3.2-9.021 + CHANGES IN spatstat.geom VERSION 3.2-9.022 OVERVIEW @@ -8,6 +8,8 @@ OVERVIEW o Tweaked plot functions. + o More support for diagram objects. + o Stability improvements and bug fixes. PACKAGE DEPENDENCE @@ -22,8 +24,20 @@ NEW FUNCTIONS o default.symbolmap.ppp Algorithm for determining the graphical symbol map used by plot.ppp. + o affine.diagramobj, reflect.diagramobj, rotate.diagramobj + Methods for geometrical transformations of diagram objects. + SIGNIFICANT USER-VISIBLE CHANGES + o identify.ppp + Automatically starts a new plot device and displays `x` + if there is no plot device open. + + o identify.psp + Identified segments are highlighted. + Automatically starts a new plot device and displays `x` + if there is no plot device open. + o plot.owin New argument 'adj.main' controls the justification of the text in the main title. @@ -95,15 +109,15 @@ DELETED FUNCTIONS BUG FIXES + o plot.ppp, default.symbolmap.ppp + Ignored 'zerosize' in some cases. + Fixed. + o symbolmap Crashed in some instances when 'inputs' was given and the graphical parameters included both functions and vectors. Fixed. - o plot.ppp, default.symbolmap.ppp - Ignored 'zerosize' in some cases. - Fixed. - CHANGES IN spatstat.geom VERSION 3.2-9 OVERVIEW diff --git a/R/diagram.R b/R/diagram.R index 7fa7d9a..752451a 100644 --- a/R/diagram.R +++ b/R/diagram.R @@ -4,7 +4,7 @@ ## Simple objects for the elements of a diagram (text, arrows etc) ## that are compatible with plot.layered and plot.solist ## -## $Revision: 1.15 $ $Date: 2024/02/04 08:04:51 $ +## $Revision: 1.18 $ $Date: 2024/06/16 02:03:14 $ # ......... internal class 'diagramobj' supports other classes ......... @@ -25,8 +25,28 @@ diagramobj <- function(X, ...) { return(y) } -shift.diagramobj <- function(X, ...) { - y <- NextMethod("shift") +# ... geometrical transformations .... + +affine.diagramobj <- function(X, ...) { + y <- NextMethod("affine") + attributes(y) <- attributes(X) + return(y) +} + +flipxy.diagramobj <- function(X) { + y <- NextMethod("flipxy") + attributes(y) <- attributes(X) + return(y) +} + +reflect.diagramobj <- function(X) { + y <- NextMethod("reflect") + attributes(y) <- attributes(X) + return(y) +} + +rotate.diagramobj <- function(X, ...) { + y <- NextMethod("rotate") attributes(y) <- attributes(X) return(y) } @@ -37,6 +57,12 @@ scalardilate.diagramobj <- function(X, f, ...) { return(y) } +shift.diagramobj <- function(X, ...) { + y <- NextMethod("shift") + attributes(y) <- attributes(X) + return(y) +} + # .............. user-accessible classes ................ # ......... (these only need a creator and a plot method) ...... diff --git a/R/ppp.R b/R/ppp.R index 10808ba..32af64e 100644 --- a/R/ppp.R +++ b/R/ppp.R @@ -4,7 +4,7 @@ # A class 'ppp' to define point patterns # observed in arbitrary windows in two dimensions. # -# $Revision: 4.116 $ $Date: 2024/04/19 09:34:39 $ +# $Revision: 4.118 $ $Date: 2024/06/16 02:03:00 $ # # A point pattern contains the following entries: # @@ -636,6 +636,9 @@ print.summary.ppp <- function(x, ..., dp=getOption("digits")) { identify.ppp <- function(x, ...) { verifyclass(x, "ppp") + if(dev.cur() == 1 && interactive()) { + eval(substitute(plot(X), list(X=substitute(x)))) + } id <- identify(x$x, x$y, ...) if(!is.marked(x)) return(id) marks <- as.data.frame(x)[id, -(1:2)] diff --git a/R/psp.R b/R/psp.R index 4dcd580..5683823 100644 --- a/R/psp.R +++ b/R/psp.R @@ -1,7 +1,7 @@ # # psp.R # -# $Revision: 1.112 $ $Date: 2024/02/04 08:04:51 $ +# $Revision: 1.116 $ $Date: 2024/06/16 02:06:24 $ # # Class "psp" of planar line segment patterns # @@ -578,27 +578,34 @@ is.empty.psp <- function(x) { return(x$n == 0) } identify.psp <- function(x, ..., labels=seq_len(nsegments(x)), n=nsegments(x), plot=TRUE) { + if(dev.cur() == 1 && interactive()) { + eval(substitute(plot(X), list(X=substitute(x)))) + } Y <- x - W <- as.owin(Y) + B <- Frame(Y) + Bplus <- grow.rectangle(B, max(sidelengths(B))/4) mids <- midpoints.psp(Y) - poz <- c(1, 2,4, 3)[(floor(angles.psp(Y)/(pi/4)) %% 4) + 1L] + poz <- c(1, 2, 4, 3)[(floor(angles.psp(Y)/(pi/4)) %% 4) + 1L] + gp <- if(plot) graphicsPars("lines") else NULL if(!(is.numeric(n) && (length(n) == 1) && (n %% 1 == 0) && (n >= 0))) stop("n should be a single integer") out <- integer(0) while(length(out) < n) { - xy <- spatstatLocator(1) - # check for interrupt exit + xy <- spatstatLocator(1, type="n") + ## check for interrupt exit if(length(xy$x) == 0) return(out) - # find nearest segment - X <- ppp(xy$x, xy$y, window=W) + ## find nearest segment + X <- ppp(xy$x, xy$y, window=Bplus) ident <- project2segment(X, Y)$mapXY - # add to list - if(ident %in% out) { + if(length(ident) == 0) { + cat("Query location is too far away\n") + } else if(ident %in% out) { cat(paste("Segment", ident, "already selected\n")) } else { + ## add to list if(plot) { - # Display + ## Display mi <- mids[ident] li <- labels[ident] po <- poz[ident] @@ -607,15 +614,20 @@ identify.psp <- function(x, ..., labels=seq_len(nsegments(x)), dont.complain.about(li, mix, miy) do.call.matched(graphics::text.default, resolve.defaults(list(x=quote(mix), - y=quote(miy), - labels=quote(li)), + y=quote(miy), + labels=quote(li)), list(...), list(pos=po))) + do.call.matched(plot.psp, + resolve.defaults(list(x=Y[ident], add=TRUE), + list(...), + list(col="blue", lwd=2)), + extrargs=gp) } out <- c(out, ident) } } - # exit if max n reached + ## exit if max n reached return(out) } diff --git a/R/solist.R b/R/solist.R index d5b2cf8..cd925e8 100644 --- a/R/solist.R +++ b/R/solist.R @@ -7,7 +7,7 @@ ## ## plot.solist is defined in plot.solist.R ## -## $Revision: 1.28 $ $Date: 2022/08/27 04:11:07 $ +## $Revision: 1.29 $ $Date: 2024/06/16 02:20:05 $ anylist <- function(...) { x <- list(...) @@ -69,9 +69,9 @@ is.sob <- local({ "funxy", "distfun", "nnfun", "lpp", "linnet", "linfun", "lintess", "influence.ppm", "leverage.ppm") - # Note 'linim' inherits 'im' - # 'dfbetas.ppm' inherits 'msr' - + ## Note 'linim' inherits 'im' + ## 'dfbetas.ppm' inherits 'msr' + ## diagram objects typically inherit 'ppp' is.sob <- function(x) { inherits(x, what=sobjectclasses) } is.sob }) diff --git a/inst/doc/packagesizes.txt b/inst/doc/packagesizes.txt index 1246a77..393c7e5 100755 --- a/inst/doc/packagesizes.txt +++ b/inst/doc/packagesizes.txt @@ -26,4 +26,4 @@ date version nhelpfiles nobjects ndatasets Rlines srclines "2023-10-20" "3.2-7" 451 1203 0 35983 15822 "2024-01-26" "3.2-8" 452 1204 0 36234 15822 "2024-02-28" "3.2-9" 452 1209 0 36325 15824 -"2024-06-15" "3.2-9.021" 443 1186 0 35690 15596 +"2024-06-16" "3.2-9.022" 443 1189 0 35731 15596 diff --git a/man/spatstat.geom-internal.Rd b/man/spatstat.geom-internal.Rd index 70563d4..29a1907 100644 --- a/man/spatstat.geom-internal.Rd +++ b/man/spatstat.geom-internal.Rd @@ -6,6 +6,7 @@ \alias{[<-.splitppx} \alias{acedist.show} \alias{acedist.noshow} +\alias{affine.diagramobj} \alias{affinexy} \alias{affinexypolygon} \alias{allElementsIdentical} @@ -80,6 +81,7 @@ \alias{fft2D} \alias{fftwAvailable} \alias{fillNA} +\alias{flipxy.diagramobj} \alias{flipxypolygon} \alias{format.numberwithunit} \alias{framebottomleft} @@ -195,6 +197,7 @@ \alias{plotWidthMap} \alias{plot.barplotdata} \alias{plot.indicfun} +\alias{pointgrid} \alias{ppllengine} \alias{pppdist.mat} \alias{pppdist.prohorov} @@ -242,18 +245,9 @@ \alias{putlastshift} \alias{qtPrepareCoordinate} \alias{quad} -\alias{rasterfilter} -\alias{recognise.spatstat.type} -\alias{rectquadrat.breaks} -\alias{rectquadrat.countEngine} -\alias{remove.identical.pairs} -\alias{repair.image.xycoords} -\alias{resolve.stringsAsFactors} -\alias{rgbNA} -\alias{ruletextline} \alias{quadscheme.replicated} \alias{quadscheme.spatial} -\alias{pointgrid} +\alias{rasterfilter} \alias{rastersample} \alias{rasterx.mask} \alias{rastery.mask} @@ -266,13 +260,22 @@ \alias{rebound.ppp} \alias{rebound.psp} \alias{rebound.owin} +\alias{rectquadrat.breaks} +\alias{rectquadrat.countEngine} +\alias{reflect.diagramobj} +\alias{remove.identical.pairs} +\alias{repair.image.xycoords} \alias{repair.old.factor.image} +\alias{resolve.stringsAsFactors} \alias{restrict.mask} \alias{reversePolyclipArgs} +\alias{rgbNA} +\alias{rotate.diagramobj} \alias{rotxy} \alias{rotxypolygon} \alias{row.names.hyperframe} \alias{row.names<-.hyperframe} +\alias{ruletextline} \alias{safedeldir} \alias{safeDevCapabilities} \alias{safelookup} @@ -352,6 +355,7 @@ \method{[}{splitppx}(x, \dots) <- value acedist.show(X, Y, n, d, timelag) acedist.noshow(X, Y, n, d) +\method{affine}{diagramobj}(X, \dots) affinexy(X, mat, vec, invert) affinexypolygon(p, mat, vec, detmat) allElementsIdentical(x, entry) @@ -429,6 +433,7 @@ fakemaintitle(bb, main, \dots) fft2D(z, inverse, west) fftwAvailable() fillNA(x, value) +\method{flipxy}{diagramobj}(X) flipxypolygon(p) \method{format}{numberwithunit}(x, \dots, collapse, modifier) framebottomleft(w) @@ -553,6 +558,7 @@ plotPolygonBdry(x, \dots) plotWidthMap(bb.leg, zlim, phys.scale, leg.scale, leg.side, leg.args, grafpar) \method{plot}{barplotdata}(x, \dots) \method{plot}{indicfun}(x, W, \dots, main) +pointgrid(W, ngrid) ppllengine(X, Y, action="project", check=FALSE) pppdist.mat(X, Y, cutoff = 1, q = 1, matching = TRUE, precision = 9, approximation = 10) @@ -602,18 +608,9 @@ project3Dhom(xyz, eye, org, vert) putlastshift(X, vec) qtPrepareCoordinate(covname, W, origin) quad(data, dummy, w, param) -rasterfilter(X, f) -recognise.spatstat.type(x) -rectquadrat.breaks(xr, yr, nx = 5, ny = nx, xbreaks = NULL, ybreaks = NULL) -rectquadrat.countEngine(x, y, xbreaks, ybreaks, weights) -remove.identical.pairs(cl, imap, jmap) -repair.image.xycoords(x) -resolve.stringsAsFactors(stringsAsFactors) -rgbNA(red, green, blue, alpha, maxColorValue) -ruletextline(ch, n, terse) quadscheme.replicated(data, dummy, method, \dots) quadscheme.spatial(data, dummy, method, \dots) -pointgrid(W, ngrid) +rasterfilter(X, f) rastersample(X, Y) rasterx.mask(w, drop) rastery.mask(w, drop) @@ -626,13 +623,23 @@ rebound(x, rect) \method{rebound}{ppp}(x, rect) \method{rebound}{psp}(x, rect) \method{rebound}{owin}(x, rect) +recognise.spatstat.type(x) +rectquadrat.breaks(xr, yr, nx = 5, ny = nx, xbreaks = NULL, ybreaks = NULL) +rectquadrat.countEngine(x, y, xbreaks, ybreaks, weights) +\method{reflect}{diagramobj}(X) +remove.identical.pairs(cl, imap, jmap) +repair.image.xycoords(x) repair.old.factor.image(x) +resolve.stringsAsFactors(stringsAsFactors) restrict.mask(M, W) reversePolyclipArgs(x, p) +rgbNA(red, green, blue, alpha, maxColorValue) +\method{rotate}{diagramobj}(X, \dots) rotxy(X, angle = pi/2) rotxypolygon(p, angle = pi/2) \method{row.names}{hyperframe}(x) \method{row.names}{hyperframe}(x) <- value +ruletextline(ch, n, terse) safedeldir(X) safeDevCapabilities() safelookup(Z, x, factor, warn)