library(urbanR)
library(ncdf4)
# -----  NO2 data:
output_path <- "/esarchive/scratch/nperez/git/Flor/Jan4Nuria/"
results <- readRDS(paste0(output_path, "bcn_NonUniformGrid.rds"))
receptor <- readRDS(paste0(output_path, "target_uniform_grid_bcn.rds"))
dates <- unique(results$date)

index <- array(1:length(dates), c(pos_index = length(dates)))
start.time <- Sys.time()
res <- multiApply::Apply(list(index), fun = regrid, non_uniform_data = results,
                         target_grid = receptor, date = dates, margins = 'pos_index',
                         ncores = 16)
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

# Save file:
 nc_path <- output_path
 var_name <- 'NO2'
 var_long_name <- "Nitrogen Dioxide Concentration"
 var_units <- "concentration in percentage"
 proj <- "+proj=longlat +datum=WGS84 +no_defs"
 timedim <- ncdim_def("time", paste("hours since", as.Date(dates[1]), "00:00:00"),
                       index - 1)
  londim <- ncdim_def("lon", "degrees_east", res$lon[,1], longname = 'longitude')
  latdim <- ncdim_def("lat", "degrees_north", res$lat[,1], longname = 'latitude')
  var_def <- ncvar_def(var_name, var_units, list(londim, latdim, timedim),
                       longname = var_long_name)
  ncout <- nc_create(file.path(nc_path, paste0(var_name, "_uniform_mesh_",
                               dates[1], ".nc")),
                     vars = var_def, force_v4 = FALSE)
  ncvar_put(ncout, var_def, res$regular)
  ncatt_put(ncout, var_name, "grid_mapping", "crs")
  ncatt_put(ncout, var_name, "proj4", proj)
  ncatt_put(ncout, 0, "date", as.character(Sys.time()))
  ncatt_put(ncout, 0, "created_by", "regrid development R function CALIOPE-urbanR")
  nc_close(ncout)


# non_uniform a data.frame with columns X and Y UTM coordinates and variables (e.g. NO2 concentration)
# target a sp object with @data data.frame with columns for spatial coordinates and and column for the expected values of the variable (e.g. NO2 filled with NAs). The projection in @proj4string needs to be the same as the provided for the non_uniform object and specified in the crs_sim. 
regrid <- function(index, non_uniform_data, target_grid, date,
                   crs_sim = "+proj=utm +zone=31 +ellps=intl +units=m +no_defs") {
  # data.frame and SpatialPointsDataFrame:
  non_uniform_data <- results[results$date == date[index],]
  non_uniform_data <- sp::SpatialPointsDataFrame(non_uniform_data[,c("X", "Y")],
                                              non_uniform_data)
  sp::proj4string(non_uniform_data) <- crs_sim

  regular <- gstat::idw(NO2 ~ 1, non_uniform_data, newdata = target_grid,
                        idp = 2.0, nmax = 4)
  regular <- sp::spTransform(regular, sp::CRS("+proj=longlat"))
  lon <- unique(round(regular@coords[,1],7))
  lat <- unique(round(regular@coords[,2],7))
  proj <- paste(regular@proj4string@projargs, "+no_defs")
  regular <- regular@data$var1.pred
  dim(regular) <- c(lon = 1450, lat = 1644)
  #if (plot == TRUE) {
  #  fields::image.plot(lon, lat, regular, main = "IDW 4 nearest neighbours",
  #                     legend.lab = "NO2 concentration",
  #                     breaks = seq(0, 100, 100/64))
  #}
  return(list(regular = regular, lat = lat, lon = lon))
}





# ----------- The target grid is already created and saved with this code ---------------------
# ---- Create uniform grid:I
crs_sim = "+proj=utm +zone=31 +ellps=intl +units=m +no_defs"
spatial_context <- context_sp(geom_path = '/esarchive/scratch/jbenavides/data/geom/')
config <- NULL
config$crs_sim <- "+proj=utm +zone=31 +ellps=intl +units=m +no_defs"
receptor_grid <- sf::st_sf(geom=sf::st_make_grid(spatial_context,
                     cellsize = 10, what = "centers"), crs=config$crs_sim)
## add coordinates required for plotting
receptor_grid$data <- cbind(receptor_grid$data, 
                            Coord_X = sf::st_coordinates(receptor_grid)[,1],
                            Coord_Y = sf::st_coordinates(receptor_grid)[,2])
receptor_grid$Coord_X <- sf::st_coordinates(receptor_grid)[,1]
receptor_grid$Coord_Y <- sf::st_coordinates(receptor_grid)[,2]
receptor <- data.frame(receptor_grid$data[,c("Coord_X", "Coord_Y")],
                     NO2 = rep(NA, 2383800))
receptor <- sp::SpatialPointsDataFrame(receptor[,c("Coord_X", "Coord_Y")],
             receptor)
sp::proj4string(receptor) <- crs_sim
receptor <- sp::spTransform(receptor, sp::CRS("+proj=longlat"))
lon_min <- 2.051908 # min(receptor@coords[,1])
lon_max <- 2.22716 # max(receptor@coords[,1])
lat_min <- 41.31932 # min(receptor@coords[,2])
lat_max <- 41.46859 # max(receptor@coords[,2])

lon <- seq(lon_min, lon_max, (lon_max - lon_min)/1449)
lat <- seq(lat_min, lat_max, (lat_max - lat_min)/1643)

lons <- rep(lon, length(lat))
lats <- sort(rep(lat, length(lon)))
receptor <- data.frame(lon = lons, lat = lats, NO2 = rep(NA, length(lons)))
receptor <- sp::SpatialPointsDataFrame(receptor[,c("lon", "lat")],
             receptor)
sp::proj4string(receptor) <- sp::CRS("+proj=longlat")
receptor <- sp::spTransform(receptor, crs_sim)
output_path <- "/esarchive/scratch/nperez/git/Flor/Jan4Nuria/"
saveRDS(receptor, file = paste0(output_path, "target_uniform_grid_bcn.rds"))
library(ggplot2)
ggplot(data = receptor@data, aes(x = lon, y = lat)) + geom_point()
# ---------------------------------------------------------

