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)))
index <- array(1:2, c(pos_index = 2))
start.time <- Sys.time()
res <- multiApply::Apply(list(index), fun = regrid, non_uniform_data = results,
                         target_grid = receptor, date = dates, margins = 'pos_index',
                         ncores = 4)
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

for (t in 1:24) { 
# t = 1
  mean_map <- results[results$date == dates[t],]
  tictoc::tic()
  mean_map_uniform <- regrid(non_uniform_data = mean_map, 
                             target_grid = receptor)
                            
 nc_path = output_path, 
                             date = format(dates[t], "%Y-%m-%d-%HH%MM"), 
                             var_name = "NO2", var_units = "concentration",
                             var_long_name = "Nitrogen dioxide")
  tictoc::toc()
}

# 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, lat, lon))
}
  timedim <- ncdim_def("time", paste("hours since", as.Date(date), "00:00:00"),
                       as.numeric(substr(date, 12, 13)))
  londim <- ncdim_def("lon", "degrees_east", lon, longname = 'longitude') 
  latdim <- ncdim_def("lat", "degrees_north", lat, 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_",
                               date, ".nc")),
                     vars = var_def, force_v4 = FALSE)
  ncvar_put(ncout, var_def, 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)
  return(regular)
}





# ----------- 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()
# ---------------------------------------------------------

regular <- mean_map_uniform
regular@data <- cbind(mean_map_uniform@data, mean_map_uniform@coords)
ggplot(data = regular@data, aes(x = lon, y = lat, pwd = 0.5, colour = var1.pred)) +
  geom_point() +
  ggtitle("IDW with 4 nearest neighbours") +
  scale_colour_gradientn(colours = rainbow(10))

regular_z <- regular@data$var1.pred
dim(regular_z) <- c(x = 1450, y = 1644)
x <- unique(regular@data$Coord_X)
y <- unique(regular@data$Coord_Y)
fields::image.plot(x, y, regular_z, main = "IDW 4 nearest neighbours",
                   legend.lab = "NO2 concentration",
                   breaks = seq(0, 100, 100/64), 
                   col = RPMG::rainbow.colors(64))
fields::image.plot(x, y, regular_z, main = "IDW 4 nearest neighbours",
                   legend.lab = "NO2 concentration",
                   breaks = seq(0, 100, 100/64))
# points on the are of BCN
ref <- sf::st_intersection(receptor_grid, districts)
ggplot() + geom_point(data = ref, aes(x = Coord_X, y = Coord_Y, colour = Coord_X))

ref_sp <- data.frame(ref$data[,c("Coord_X", "Coord_Y")],
                     NO2 = rep(NA, 1020625))
ref_sp <- sp::SpatialPointsDataFrame(ref_sp[,c("Coord_X", "Coord_Y")], ref_sp)

sp::proj4string(ref_sp) <- crs_sim
sp::proj4string(mean_map_sp) <- crs_sim

res <- gstat::idw(NO2 ~ 1, mean_map_sp, newdata = ref_sp, idp = 2.0)

res@data <- cbind(res@data, res@coords) 
ggplot(data = res@data, aes(x = Coord_X, y = Coord_Y, colour = var1.pred)) +
  geom_point()



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)


mean_map_sf <- mean_map %>% sf::st_as_sf(coords = c("X", "Y"), crs = crs_sim)

bcn_mean_map <- mean_map_sf
bcn_mean_map$Coord_X <- sf::st_coordinates(bcn_mean_map)[,1]
bcn_mean_map$Coord_Y <- sf::st_coordinates(bcn_mean_map)[,2]

bcn_mean_map <- sf::st_transform(bcn_mean_map,crs("+proj=longlat"))
bcn_mean_map$X <- sf::st_coordinates(bcn_mean_map)[,1]
bcn_mean_map$Y <- sf::st_coordinates(bcn_mean_map)[,2]

points <- sp::SpatialPoints(methods::as(bcn_mean_map[,c('X','Y')], "Spatial"),
              proj4string = sp::CRS("+proj=longlat"))
mean_map_sp <- SpatialPointsDataFrame(mean_map[,c("X", "Y")], mean_map)
ggplot(data=mean_map_sp@data, aes(x = X, y = Y, colour = NO2)) + geom_point()
