Skip to content

combining identify() and locator()

4 messages · Brian Bolt, Barry Rowlingson

#
Hi,
I am wondering if there might be a way to combine the two functions  
identify() and locator() such that if I use identify() and then click  
on a point outside the set tolerance, the x,y coordinates are returned  
as in locator().  Does anyone know of a way to do this?
Thanks in advance for any help
-brian
#
2009/2/27 Brian Bolt <bbolt at kalypsys.com>:
Since "identify" will only return the indexes of selected points, and
it only takes on-screen clicks for coordinates, you'll have to
leverage "locator" and duplicate some of the "identify" work. So call
locator(1), then compute the distancez to your points, and if any are
below your tolerance mark them using text(), otherwise keep the
coordinates of the click.

 You can use dist() to compute a distance matrix, but if you want to
totally replicate identify's tolerance behaviour I think you'll have
to convert from your data coordinates to device coordinates. The
grconvertX and Y functions look like they'll do that for you.

 Okay, that's the flatpack delivered, I think you've got all the
parts, some assembly required!

Barry
#
awesome.  Thank you very much for the quick response. I think this is  
exactly what I was looking for.
-Brian
On Feb 27, 2009, at 1:10 AM, Barry Rowlingson wrote:

            
#
2009/2/27 Brian Bolt <bbolt at kalypsys.com>:
Here's a basic framework:

 `idloc` <-
  function(xy,n=1, tol=0.25){

    tol2=tol^2

    icoords = cbind(grconvertX(xy[,1],to="inches"),grconvertY(xy[,2],to="inches"))
    hit = c()
    missed = matrix(ncol=2,nrow=0)
    for(i in 1:n){
      ptU = locator(1)
      pt = c(grconvertX(ptU$x,to='inches'),grconvertY(ptU$y,to="inches"))

      d2 = (icoords[,1]-pt[1])^2 + (icoords[,2]-pt[2])^2
      if (any(d2 < tol2)){
        print("clicked")
        hit = c(hit, (1:dim(xy)[1])[d2 < tol2])
      }else{
        print("missed")
        missed=rbind(missed,c(ptU$x,ptU$y))
      }

    }
    return(list(hit=hit,missed=missed))

  }

Test:

 xy = cbind(1:10,runif(10))
 plot(xy)
 idloc(xy,10)

 now click ten times, on points or off points. You get back:

$hit
[1]  4  6  7 10

$missed
         [,1]      [,2]
[1,] 5.698940 0.6835392
[2,] 6.216171 0.6144229
[3,] 5.877982 0.5752569
[4,] 6.773190 0.2895761
[5,] 7.210847 0.3126149
[6,] 9.239985 0.5614337

 - $hit is the indices of the points you hit (in order, including
duplicates) and $missed are the coordinates of the misses.

 It crashes out if you hit the middle button for the locator, but that
should be easy enough to fixup. It doesn't label hit points, but
that's also easy enough to do.

Barry