
# Creation: 6/2016
# Author: Nicola Cortesi
# Aim:   Remove the grid points above a certain value (argument 'level') [and below '-level' if two.sides=TRUE] that happens to be in areas with few points above that value.
#        Useful to remove from a contour plot all the small spots of significative points that we don't want to contour.
#        To do so, just apply this function inside the option 'contour' of 'PlotEquiMap' to remove the significative points (they are set to the value of 0).
#        Argument 'size' determines the side of the square (in grid points) used to find if there are enough grid points with values above 'level' nearby
#        the chosen point or not. Increasing it will incresase the number of grid points deleted, leaving only the bigger spots of points above the chosen value.
# I/O:   a 2D lat/lon grid in geographic coordinates
# Assumptions: none
# Branch: general
#
# Example:
# data <- matrix(runif(48000,0,1)^2,300,160) + matrix(c(rep(0,20000),rep(0.6,3000),rep(0,25000)),300,160)
# PlotEquiMap(data,lon=1:300,lat=-80:79,filled.continents=F,cols=c("white","yellow","orange","red","darkred"))
# PlotEquiMap(data,lon=1:300,lat=-80:79,filled.continents=F,cols=c("white","yellow","orange","red","darkred"), contours=data, brks2=0.6)
# PlotEquiMap(data,lon=1:300,lat=-80:79,filled.continents=F,cols=c("white","yellow","orange","red","darkred"), contours=grid2contour(data,0.6,FALSE,5), brks2=0.6, contours.labels=FALSE)
# PlotEquiMap_colored(data,lon=1:300,lat=-80:79,filled.continents=F,cols=c("white","yellow","orange","red","darkred"), contours=grid2contour(data,0.6,FALSE,5), brks2=0.6, contours.labels=FALSE, contours.col="blue", continents.col="gray40")

grid2contour <- function(grid, level, two.sides=FALSE, size=10){
  nrows <- dim(grid)[1]
  ncols <- dim(grid)[2]
  radius <- round(size/2)
  
  grid.weighted <- matrix(NA, nrows, ncols)
  
  grid.expanded <- rbind(cbind(grid[nrows:1,((ncols/2)+1):ncols],grid[nrows:1,],grid[nrows:1,],grid[nrows:1,1:(ncols/2)]),cbind(grid,grid,grid),cbind(grid[nrows:1,((ncols/2)+1):ncols],grid[nrows:1,],grid[nrows:1,],grid[nrows:1,1:(ncols/2)]))
  
  if(two.sides==FALSE){
    for(i in 1:nrows){
      for(j in 1:ncols){
        grid.weighted[i,j] <- sum(grid.expanded[(nrows+i-radius):(nrows+i+radius),(ncols+j-radius):(ncols+j+radius)] < level)
      }
    }
  } else {
    for(i in 1:nrows){
      for(j in 1:ncols){
        grid.weighted[i,j] <- sum(grid.expanded[(nrows+i-radius):(nrows+i+radius),(ncols+j-radius):(ncols+j+radius)] < level) + sum(grid.expanded[(nrows+i-radius):(nrows+i+radius),(ncols+j-radius):(ncols+j+radius)] > -level)
      }
    }  
  }
  
  n.points.min <- (2*radius+1)^2*0.3 # 30% of the total points in the square
  ss <- which(grid.weighted < n.points.min)
  grid[ss] <- 1
  return(grid)
}