From b71f28071894809c380517659d8b6bab97ca815d Mon Sep 17 00:00:00 2001 From: MGousseff Date: Thu, 5 Oct 2023 09:36:33 +0200 Subject: [PATCH 01/18] Fixed importLCZvect : drop = TRUE did'nt keep all the column. Also fixed a deprecated tidyr syntax. --- R/importLCZvect.R | 34 ++++++++++++++---------------- inst/tinytest/test_importLCZvect.R | 9 +++++++- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/R/importLCZvect.R b/R/importLCZvect.R index 730f8fe..6d2b443 100644 --- a/R/importLCZvect.R +++ b/R/importLCZvect.R @@ -51,7 +51,9 @@ importLCZvect<-function(dirPath, file="rsu_lcz.geojson", output="sfFile", column colErr<-c("It seems that some of the columns you try to import do not exist in the source file, are you sure you meant ", paste(badCol)," ?") - if (prod(inCol)==0){ stop(colErr) } else { sfFile<-sf::st_read(dsn=fileName,quiet=!verbose)[,colonnes] } + if (prod(inCol)==0){ stop(colErr) } else { + if (drop== TRUE) {sfFile<-sf::st_read(dsn=fileName,quiet=!verbose)[,colonnes] } else {sfFile<-sf::st_read(dsn=fileName,quiet=!verbose)[,]} + } # if typeLevels is empty if (length(typeLevels)==1){ @@ -60,20 +62,16 @@ importLCZvect<-function(dirPath, file="rsu_lcz.geojson", output="sfFile", column } # if typeLevels is not specified it will be set to default and we need to capture this later - typeLevelsDefault<-c("1"="1","2"="2","3"="3","4"="4","5"="5","6"="6","7"="7","8"="8", - "9"="9","10"="10","101"="101","102"="102","103"="103","104"="104", - "105"="105","106"="106","107"="107","101"="11","102"="12","103"="13","104"="14", - "105"="15", "106"="16","107"="17") + # typeLevelsDefault<-c("1"="1","2"="2","3"="3","4"="4","5"="5","6"="6","7"="7","8"="8", + # "9"="9","10"="10","101"="101","102"="102","103"="103","104"="104", + # "105"="105","106"="106","107"="107","101"="11","102"="12","103"="13","104"="14", + # "105"="15", "106"="16","107"="17") # Select columns from original file - if (column!=""){ - if(drop==T){sfFile<-subset(sfFile,select=colonnes)} - - - prov<-as.character(unique((st_drop_geometry(subset(sfFile,select=column,drop=T))))) %>% as.character - names(prov)<-prov - - if( prod(prov%in%typeLevels)==0 ){ - if (verbose==TRUE){ +if (column!=""){ + prov<-as.character(unique((st_drop_geometry(subset(sfFile,select=column,drop=T))))) %>% as.character + names(prov)<-prov + if( prod(prov%in%typeLevels)==0 ) { + if (verbose==TRUE){ print("levels in typeLevels are : ") print(typeLevels) print("levels in original data set are ") @@ -83,7 +81,7 @@ importLCZvect<-function(dirPath, file="rsu_lcz.geojson", output="sfFile", column Some geoms have been dropped,this could seriously alter your analysis, please check the levels or enter an empty string as typeLevels") } - if( sum(prov%in%typeLevels)==0 ){ + if( sum(prov%in%typeLevels)==0 ){ stop( paste0("none of the levels present in ",column, " is covered by the levels you specified.", @@ -92,7 +90,6 @@ importLCZvect<-function(dirPath, file="rsu_lcz.geojson", output="sfFile", column " must contain LCZ types in a standard format")) } - sfFile <- sfFile%>% mutate(!!column:=fct_recode(factor(subset(sfFile,select=column,drop=T),levels=typeLevels),!!!typeLevels)) %>% @@ -104,8 +101,9 @@ importLCZvect<-function(dirPath, file="rsu_lcz.geojson", output="sfFile", column #sfFile <- sfFile%>% mutate(!!column:=fct_recode(subset(sfFile,select=column,drop=T),!!!typeLevels)) if(output=="sfFile"){return(sfFile)} else { - if(output=="bBox"){bBox<-st_bbox(sfFile,crs=st_crs(sfFile)) %>% st_as_sfc - return(bBox)} + if(output=="bBox"){ + bBox<-st_bbox(sfFile,crs=st_crs(sfFile)) %>% st_as_sfc + return(bBox) } else { stop("Output must be sfFile to return geoms and LCZ or bBox to return the bounding box")} diff --git a/inst/tinytest/test_importLCZvect.R b/inst/tinytest/test_importLCZvect.R index 4d18238..7efec9c 100644 --- a/inst/tinytest/test_importLCZvect.R +++ b/inst/tinytest/test_importLCZvect.R @@ -98,4 +98,11 @@ expect_warning(importLCZvect(dirPath=paste0(system.file("extdata", package = "lc "9"="9","10"="10","101"="101","102"="102","103"="103","104"="104", "105"="105","106"="106","101"="11","102"="12","103"="13","104"="14", "105"="15", "106"="16","107"="17"),drop=T), - "The levels you specified with the typeLevels argument don't cover the LCZ values") \ No newline at end of file + "The levels you specified with the typeLevels argument don't cover the LCZ values") + + +# test if the drop argument allows to keep or drop comun other than specified +test<-importLCZvect(dirPath=paste0( + system.file("extdata", package = "lczexplore"),"/bdtopo_2_2/Redon"),file="rsu_lcz.geojson", + column="LCZ_PRIMARY",geomID="ID_RSU",confid="LCZ_UNIQUENESS_VALUE",drop=FALSE) +expect_equal("LCZ_SECONDARY"%in%names(test),TRUE) \ No newline at end of file From 39548b941ae9d92a8af6073cd29f67e0d22ed9a0 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Fri, 6 Oct 2023 17:02:41 +0200 Subject: [PATCH 02/18] geoClimateConfigFile creates a json config file for geoclimate with the user agruments geoClimateCall feeds the system with a command launching the specified jar file and feeding it the specified config file and workflow --- R/geoClimateCall.R | 23 +++++++++++++ R/geoClimateConfigFile.R | 71 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 R/geoClimateCall.R create mode 100644 R/geoClimateConfigFile.R diff --git a/R/geoClimateCall.R b/R/geoClimateCall.R new file mode 100644 index 0000000..470f744 --- /dev/null +++ b/R/geoClimateCall.R @@ -0,0 +1,23 @@ +geoClimateCall<-function(jarFilePath,configFilePath,wf="OSM") { + command<-paste0( + "java -jar ", jarFilePath, " -f ", configFilePath, " -w ", wf) + print(command) + system(command) + +} + +test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", + rsuIndics = c("LCZ","TEB","UTRF"), + gridIndics = c("BUILDING_FRACTION", + "BUILDING_HEIGHT", + "WATER_FRACTION", + "VEGETATION_FRACTION", + "ROAD_FRACTION", + "IMPERVIOUS_FRACTION", + "LCZ_PRIMARY", + "LCZ_FRACTION", + "UTRF")) +geoClimateCall( + jarFilePath= + "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", + configFilePath="/tmp/Redonosm.json",w="osm") \ No newline at end of file diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R new file mode 100644 index 0000000..efce515 --- /dev/null +++ b/R/geoClimateConfigFile.R @@ -0,0 +1,71 @@ +#library(jsonlite) +geoClimateConfigFile<-function(locations, wf, + outFolder="/tmp", + rsuIndics=c("LCZ","TEB","UTRF"), + svSimplified = TRUE, + estimatedHeight=TRUE, + grid_x_size=100, + grid_y_size=100, + rowCol=FALSE, + outputType="geojson", + gridIndics=c("BUILDING_FRACTION", + "BUILDING_HEIGHT", + "WATER_FRACTION", + "VEGETATION_FRACTION", + "ROAD_FRACTION", + "IMPERVIOUS_FRACTION", + "LCZ_PRIMARY", + "LCZ_FRACTION", + "UTRF"), + outDir = "/tmp", + outFile="") { +if (wf=="osm"){description<-"Processing OSM data"} else { + if (wf=="bdt2") {description<-"Processing BDTopo v2 data"} +} + +# description<-list(description = description) +# input<-list(input=list(locations=locations)) + +outFolder<-list(folder=unbox(outFolder)) + +parameters<-list( + rsu_indicators = list( + indicatorUse = rsuIndics, + svSimplified = unbox(svSimplified), + estimatedHeight = unbox(estimatedHeight)), + grid_indicators = list( + x_size = unbox(grid_x_size), y_size = unbox(grid_y_size), + rowCol = unbox(rowCol), + output = unbox(outputType), + indicators = gridIndics + ) +) + + +listJSON = list(description=description,input=list(locations=locations),output=outFolder,parameters=parameters) + +output<-toJSON(x=listJSON, + pretty=TRUE) + + +if (outFile=="") { outFile=paste0(locations,wf) } + +write(output,file=paste0(outDir,"/",outFile,".json")) + +return(output) + +} + +test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", + rsuIndics = c("LCZ","TEB","UTRF"), + gridIndics = c("BUILDING_FRACTION", + "BUILDING_HEIGHT", + "WATER_FRACTION", + "VEGETATION_FRACTION", + "ROAD_FRACTION", + "IMPERVIOUS_FRACTION", + "LCZ_PRIMARY", + "LCZ_FRACTION", + "UTRF")) +test +write("test",file=paste0("/tmp","/","test.txt")) \ No newline at end of file From a7116d11eda8351e8075e1033c75a97add29e8e8 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Fri, 6 Oct 2023 17:57:56 +0200 Subject: [PATCH 03/18] Just draft of the needed structure to code a shiny interface in order to call GeoClimate with OSM Data. --- R/shinyGC/app.R | 54 +++++++++++++++++++++++++++++++++++++++ R/shinyGC/launchShinyGC.R | 1 + 2 files changed, 55 insertions(+) create mode 100644 R/shinyGC/app.R create mode 100644 R/shinyGC/launchShinyGC.R diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R new file mode 100644 index 0000000..3efcb38 --- /dev/null +++ b/R/shinyGC/app.R @@ -0,0 +1,54 @@ +library(shiny) + +# Define UI for app that draws a histogram ---- +ui <- fluidPage( + + # App title ---- + titlePanel("Run Geoclimate with OSM Data on a location"), + + # Sidebar layout with input and output definitions ---- + sidebarLayout( + + # Sidebar panel for inputs ---- + sidebarPanel( + + # Input: Slider for the number of bins ---- + + + ), + + # Main panel for displaying outputs ---- + mainPanel( + + # Output: Histogram ---- + plotOutput(outputId = "distPlot") + + ) + ) +) + +# Define server logic required to draw a histogram ---- +server <- function(input, output) { + + # Histogram of the Old Faithful Geyser Data ---- + # with requested number of bins + # This expression that generates a histogram is wrapped in a call + # to renderPlot to indicate that: + # + # 1. It is "reactive" and therefore should be automatically + # re-executed when inputs (input$bins) change + # 2. Its output type is a plot + output$distPlot <- renderPlot({ + + x <- faithful$waiting + bins <- seq(min(x), max(x), length.out = input$bins + 1) + + hist(x, breaks = bins, col = "#007bc2", border = "white", + xlab = "Waiting time to next eruption (in mins)", + main = "Histogram of waiting times") + + }) + +} + +shinyApp(ui = ui, server = server) \ No newline at end of file diff --git a/R/shinyGC/launchShinyGC.R b/R/shinyGC/launchShinyGC.R new file mode 100644 index 0000000..b5427f1 --- /dev/null +++ b/R/shinyGC/launchShinyGC.R @@ -0,0 +1 @@ +shiny::runApp("/home/gousseff/Documents/2_CodesSources/R/lczexploreCleanOrbisgis/lczexplore/R/shinyGC/") From 618773fea5f7db481545bebb6ec968821f80de1c Mon Sep 17 00:00:00 2001 From: MGousseff Date: Mon, 9 Oct 2023 11:53:44 +0200 Subject: [PATCH 04/18] geoClimateConfigFile and GeoClimateCall documented --- NAMESPACE | 4 +++ R/geoClimateCall.R | 38 +++++++++++++++------------ R/geoClimateConfigFile.R | 56 +++++++++++++++++++++++++++++----------- R/shinyGC/app.R | 45 +++++++++++++++----------------- 4 files changed, 87 insertions(+), 56 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index ba26ad4..34073d4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,8 @@ export(areColors) export(compareLCZ) export(confidSensib) export(fetchLCZ) +export(geoClimateCall) +export(geoClimateConfigFile) export(groupLCZ) export(importLCZgc) export(importLCZraster) @@ -35,6 +37,8 @@ importFrom(ggplot2,geom_sf) importFrom(ggplot2,ggtitle) importFrom(ggplot2,guides) importFrom(grDevices,palette.colors) +importFrom(jsonlite,toJSON) +importFrom(jsonlite,unbox) importFrom(magrittr,"%>%") importFrom(stats,quantile) importFrom(terra,as.polygons) diff --git a/R/geoClimateCall.R b/R/geoClimateCall.R index 470f744..b6a54c3 100644 --- a/R/geoClimateCall.R +++ b/R/geoClimateCall.R @@ -1,23 +1,27 @@ +#' Calls GeoClimate and feeds it a configuration file by building a command an using system (only tested on linux) +#' @param jarFilePath tells where the geoclimate jar file is, default points to the embedded jar file, +#' i.e. the latest snapshot version when the package was built. +#' Versions can be downloaded from https://github.com/orbisgis/geoclimate/wiki/Download +#' @param configFilePath points to the configuration JSON file for GeoClimate, typically a file created with the +#' geoClimateConfigFile function +#' @param wf is the workflow to use with GeoClimate, the default is OSM for OpenStreetMap. +#' The other possible value is "BDTOPO_V2". Other values will be added (e.g. for BDTOPO_V3) when tested. +#' @return returns nothing but files will be created by GeoClimate in the folder specified in the +#' JSON configuration file. +#' @export +#' @examples +#' test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", +#' rsuIndics = c("LCZ","TEB","UTRF"), +#' gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", +#' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) +#' geoClimateCall( +#' jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", +#' configFilePath="/tmp/Redonosm.json",w="osm") +#' test geoClimateCall<-function(jarFilePath,configFilePath,wf="OSM") { command<-paste0( "java -jar ", jarFilePath, " -f ", configFilePath, " -w ", wf) print(command) system(command) -} - -test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", - rsuIndics = c("LCZ","TEB","UTRF"), - gridIndics = c("BUILDING_FRACTION", - "BUILDING_HEIGHT", - "WATER_FRACTION", - "VEGETATION_FRACTION", - "ROAD_FRACTION", - "IMPERVIOUS_FRACTION", - "LCZ_PRIMARY", - "LCZ_FRACTION", - "UTRF")) -geoClimateCall( - jarFilePath= - "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", - configFilePath="/tmp/Redonosm.json",w="osm") \ No newline at end of file +} \ No newline at end of file diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R index efce515..c9e22b7 100644 --- a/R/geoClimateConfigFile.R +++ b/R/geoClimateConfigFile.R @@ -1,5 +1,38 @@ -#library(jsonlite) -geoClimateConfigFile<-function(locations, wf, +#' Builds a JSON configuration file for GeoClimate workflow +#' @param locations is either the town or the coordinates of the bounding box of the area on which GeoClimate will run. +#' If a town name, it will be fed to the Nominoe API, through the overpass API of OpenStreetMap. +#' @param wf is the workflow used by GeoClimate. For now, only osm is available, for OpenStreetMap, but bdt for +#' BD TOPO of IGN should be added when an online database is available. +#' @param outFolder indicates where the results of GeoClimate will be put +#' @param rsuIndics is a vector with the indicators one wants to compute at the RSU scale. The default is c("LCZ","TEB","UTRF"), +#' @param svSimplified uses the simplified method to calculate skyview factor, default = TRUE +#' @param estimatedHeight uses an algorithm to esitmate the missing building height, default = TRUE +#' @param grid_x_size is the x size for the grid if some grid indicators are to be computed, default=100 +#' @param grid_y_size is the x size for the grid if some grid indicators are to be computed, default=100 +#' @param rowCol if grid_x_size and grid_y_size are not set, one cal set the number of rows and cols throug rowCol, +#' but the recommended and defualt is FALSE +#' @param outputType is the format of GeoClimate outputs, default="geojson", +#' @param gridIndics is a vector containing the indicators to compute at the grid scale. Default is +#' c("BUILDING_FRACTION", +#' "BUILDING_HEIGHT", +#' "WATER_FRACTION", +#' "VEGETATION_FRACTION", +#' "ROAD_FRACTION", +#' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF") +#' @param outDir is the folder were the resulting JSON file will be put, the folder where GeoClimate will read it from +#' (different from out outFolder, where GeoClimates will put its geoJSON ouputs), default is "/tmp" +#' @param outFile is the name of your configuration file, if anb empty string, a name woill be created from location +#' and workflow parameters. +#' @importFrom jsonlite unbox toJSON +#' @return returns a JSON configuration file to be fed to GeoClimate +#' @export +#' @examples +#' test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", +#' rsuIndics = c("LCZ","TEB","UTRF"), +#' gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", +#' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) +#' test +geoClimateConfigFile<-function(locations, wf, outFolder="/tmp", rsuIndics=c("LCZ","TEB","UTRF"), svSimplified = TRUE, @@ -56,16 +89,9 @@ return(output) } -test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", - rsuIndics = c("LCZ","TEB","UTRF"), - gridIndics = c("BUILDING_FRACTION", - "BUILDING_HEIGHT", - "WATER_FRACTION", - "VEGETATION_FRACTION", - "ROAD_FRACTION", - "IMPERVIOUS_FRACTION", - "LCZ_PRIMARY", - "LCZ_FRACTION", - "UTRF")) -test -write("test",file=paste0("/tmp","/","test.txt")) \ No newline at end of file + test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", + rsuIndics = c("LCZ","TEB","UTRF"), + gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", + "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) + test + diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R index 3efcb38..79df1d9 100644 --- a/R/shinyGC/app.R +++ b/R/shinyGC/app.R @@ -4,16 +4,16 @@ library(shiny) ui <- fluidPage( # App title ---- - titlePanel("Run Geoclimate with OSM Data on a location"), + titlePanel("Run Geoclimate on OSM Data"), # Sidebar layout with input and output definitions ---- sidebarLayout( # Sidebar panel for inputs ---- sidebarPanel( - - # Input: Slider for the number of bins ---- - + textInput(inputId="location",label="Enter your locations here", + value="Redon",placeholder="A town name or some coordinates") + ), @@ -21,7 +21,10 @@ ui <- fluidPage( mainPanel( # Output: Histogram ---- - plotOutput(outputId = "distPlot") + renderText( + + + ) ) ) @@ -29,25 +32,19 @@ ui <- fluidPage( # Define server logic required to draw a histogram ---- server <- function(input, output) { - - # Histogram of the Old Faithful Geyser Data ---- - # with requested number of bins - # This expression that generates a histogram is wrapped in a call - # to renderPlot to indicate that: - # - # 1. It is "reactive" and therefore should be automatically - # re-executed when inputs (input$bins) change - # 2. Its output type is a plot - output$distPlot <- renderPlot({ - - x <- faithful$waiting - bins <- seq(min(x), max(x), length.out = input$bins + 1) - - hist(x, breaks = bins, col = "#007bc2", border = "white", - xlab = "Waiting time to next eruption (in mins)", - main = "Histogram of waiting times") - - }) + + output$configFile<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations=input$location, + rsuIndics = c("LCZ","TEB","UTRF"), + gridIndics = c("BUILDING_FRACTION", + "BUILDING_HEIGHT", + "WATER_FRACTION", + "VEGETATION_FRACTION", + "ROAD_FRACTION", + "IMPERVIOUS_FRACTION", + "LCZ_PRIMARY", + "LCZ_FRACTION", + "UTRF")) + } From b9ac649cd4f3a34bf5dbd8a48472be59be5ce746 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Mon, 9 Oct 2023 16:05:52 +0200 Subject: [PATCH 05/18] Added to the Shiny App the choice of the folder in which GeoClimate outputs its results --- R/geoClimateCall.R | 19 ++++++++++- R/geoClimateConfigFile.R | 10 +++--- R/shinyGC/app.R | 72 ++++++++++++++++++++++++++-------------- 3 files changed, 71 insertions(+), 30 deletions(-) diff --git a/R/geoClimateCall.R b/R/geoClimateCall.R index b6a54c3..a431a35 100644 --- a/R/geoClimateCall.R +++ b/R/geoClimateCall.R @@ -24,4 +24,21 @@ geoClimateCall<-function(jarFilePath,configFilePath,wf="OSM") { print(command) system(command) -} \ No newline at end of file +} + +test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Allaire", + rsuIndics = c("LCZ","TEB","UTRF"), + gridIndics = c("BUILDING_FRACTION", + "BUILDING_HEIGHT", + "WATER_FRACTION", + "VEGETATION_FRACTION", + "ROAD_FRACTION", + "IMPERVIOUS_FRACTION", + "LCZ_PRIMARY", + "LCZ_FRACTION", + "UTRF")) + + geoClimateCall( + jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", + configFilePath="/tmp/Redonosm.json",w="osm") + test \ No newline at end of file diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R index c9e22b7..469a98b 100644 --- a/R/geoClimateConfigFile.R +++ b/R/geoClimateConfigFile.R @@ -89,9 +89,9 @@ return(output) } - test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", - rsuIndics = c("LCZ","TEB","UTRF"), - gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", - "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) - test + # test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Allaire", + # rsuIndics = c("LCZ","TEB","UTRF"), + # gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", + # "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) + # test diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R index 79df1d9..85c4798 100644 --- a/R/shinyGC/app.R +++ b/R/shinyGC/app.R @@ -1,4 +1,6 @@ library(shiny) +library(shinyFiles) +library(lczexplore) # Define UI for app that draws a histogram ---- ui <- fluidPage( @@ -8,43 +10,65 @@ ui <- fluidPage( # Sidebar layout with input and output definitions ---- sidebarLayout( - + # Sidebar panel for inputs ---- sidebarPanel( textInput(inputId="location",label="Enter your locations here", - value="Redon",placeholder="A town name or some coordinates") - - + value="Redon",placeholder="A town name or some coordinates"), + shinyDirButton('outFolder', 'Output folder for GeoClimates results', 'Select the folder where GeoClimates will output its results', FALSE) ), # Main panel for displaying outputs ---- mainPanel( - - # Output: Histogram ---- - renderText( - - - ) - + titlePanel(title="Here is the content of the JSON configuration file you are building"), + + verbatimTextOutput("configJSON", ), + verbatimTextOutput("outFolder", placeholder = TRUE) ) + ) ) + # Define server logic required to draw a histogram ---- server <- function(input, output) { - - output$configFile<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations=input$location, - rsuIndics = c("LCZ","TEB","UTRF"), - gridIndics = c("BUILDING_FRACTION", - "BUILDING_HEIGHT", - "WATER_FRACTION", - "VEGETATION_FRACTION", - "ROAD_FRACTION", - "IMPERVIOUS_FRACTION", - "LCZ_PRIMARY", - "LCZ_FRACTION", - "UTRF")) - + + # test<-geoClimateConfigFile( + # outFile="", wf="osm",outFolder="/tmp",locations=input$location, + # rsuIndics = c("LCZ","TEB","UTRF"),gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT", + # "WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION","IMPERVIOUS_FRACTION","LCZ_PRIMARY", + # "LCZ_FRACTION","UTRF")) + + shinyFiles::shinyDirChoose(input, 'outFolder', roots=getVolumes()(), + filetypes=c('', 'txt'),defaultPath = "" ) + + # observeEvent(input$outFolder, { + # if (!is.null(input$dir)) { + # dir_path <- input$dir + # if (!file.exists(dir_path)) { + # dir.create(dir_path) + # showModal(modalDialog( + # title = "Folder Created", + # "The folder has been created.", + # easyClose = TRUE + # )) + # } + # } + # } + # ) + + outFolder<-reactive(input$outFolder) + output$outFolder<-renderText({gsub("//","/",parseDirPath(roots=getVolumes()(), selection=outFolder()))}) + + output$configJSON<-renderText({geoClimateConfigFile( + outFile="", wf="osm", + outFolder=gsub("//","/",parseDirPath(roots=getVolumes()(), selection=outFolder())), + locations=input$location, + rsuIndics = c("LCZ","TEB","UTRF"),gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT", + "WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION","IMPERVIOUS_FRACTION","LCZ_PRIMARY", + "LCZ_FRACTION","UTRF"))}) + + } From fa49324b10a93ae2d6cd347eb001dabb19e84bab Mon Sep 17 00:00:00 2001 From: MGousseff Date: Thu, 12 Oct 2023 17:54:19 +0200 Subject: [PATCH 06/18] commit geoCmlimateConfigFile as it seems uncommited it won't be seen by app.R --- R/geoClimateConfigFile.R | 47 ++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R index 469a98b..fa00d05 100644 --- a/R/geoClimateConfigFile.R +++ b/R/geoClimateConfigFile.R @@ -51,17 +51,39 @@ geoClimateConfigFile<-function(locations, wf, "LCZ_FRACTION", "UTRF"), outDir = "/tmp", - outFile="") { -if (wf=="osm"){description<-"Processing OSM data"} else { - if (wf=="bdt2") {description<-"Processing BDTopo v2 data"} -} + outFile="", + BDTinFolder="",BDTinseeCode=29301) { + print(wf) + + description<-"Test de description unique" + + # if (wf=="OSM"){description<-"Processing OSM data"} else { + # if (wf=="BDTOPO_V2.2") {description<-"Processing BDTopo v2 data"} else { + # if (wf=="BDTOPO_V3") { + # description<-"Processing BDTopo v2 data"} + # else { description<-paste0("Processing on an unrecognized workflow: ", wf) + # } + # } + # } + + # description<-list(description = description) # input<-list(input=list(locations=locations)) - + outFolder<-list(folder=unbox(outFolder)) -parameters<-list( + +# if (wf == "osm"){ + input=list(locations=locations) +# } else {if (grep("BDT",wf)) { +# input=list(folder=BDTinFolder,locations=BDTinseeCode) +# } +# } + + + + parameters<-list( rsu_indicators = list( indicatorUse = rsuIndics, svSimplified = unbox(svSimplified), @@ -75,7 +97,7 @@ parameters<-list( ) -listJSON = list(description=description,input=list(locations=locations),output=outFolder,parameters=parameters) +listJSON = list(input=input,output=outFolder,parameters=parameters) #description=unbox(description), output<-toJSON(x=listJSON, pretty=TRUE) @@ -89,9 +111,10 @@ return(output) } - # test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Allaire", - # rsuIndics = c("LCZ","TEB","UTRF"), - # gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", - # "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) - # test +# library(jsonlite) +# test<-geoClimateConfigFile(outFile="", wf="BDTOPO_V2.2",outFolder="/tmp",locations="Allaire", +# rsuIndics = c("LCZ","TEB","UTRF"), +# gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", +# "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) +# test From cf21465299ebcbb1ab7ffecd5f71750ccd72aaa5 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Thu, 12 Oct 2023 18:13:39 +0200 Subject: [PATCH 07/18] commit geoCmlimateConfigFile as it seems uncommited it won't be seen by app.R --- R/shinyGC/app.R | 81 ++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R index 85c4798..a064c80 100644 --- a/R/shinyGC/app.R +++ b/R/shinyGC/app.R @@ -13,16 +13,29 @@ ui <- fluidPage( # Sidebar panel for inputs ---- sidebarPanel( + shinyDirButton(id = "outFolder", + label = "Output folder for GeoClimates results", + title = "Select the folder where GeoClimates will output its results", FALSE), + selectInput(inputId="wf", label="Workflow", + choices = list(OpenStreetMap="OSM","BD TOPO V2"="BDTOPO_V2.2","BD TOPO V3"="BDTOPO_V3"), + selected=list(OpenStreetMap="OSM")), + conditionalPanel( + condition='input.wf!="OSM"', + shinyDirButton("inBDTfolder", + label = "BD_TOPO folder", + title = "Choose in which folder are the BD_TOPO files"), + numericInput(inputId="inseeCode", label="Enter Insee code of your location (town)", value = "29031") + ), textInput(inputId="location",label="Enter your locations here", - value="Redon",placeholder="A town name or some coordinates"), - shinyDirButton('outFolder', 'Output folder for GeoClimates results', 'Select the folder where GeoClimates will output its results', FALSE) + value="Redon",placeholder="A town name or some coordinates") + ), # Main panel for displaying outputs ---- mainPanel( titlePanel(title="Here is the content of the JSON configuration file you are building"), - verbatimTextOutput("configJSON", ), + verbatimTextOutput("configJSON"), verbatimTextOutput("outFolder", placeholder = TRUE) ) @@ -33,40 +46,46 @@ ui <- fluidPage( # Define server logic required to draw a histogram ---- server <- function(input, output) { - # test<-geoClimateConfigFile( - # outFile="", wf="osm",outFolder="/tmp",locations=input$location, - # rsuIndics = c("LCZ","TEB","UTRF"),gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT", - # "WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION","IMPERVIOUS_FRACTION","LCZ_PRIMARY", - # "LCZ_FRACTION","UTRF")) + # Choose the folder where results of geoclimate will be put + # set the path to the button in the interface (input outfolder) shinyFiles::shinyDirChoose(input, 'outFolder', roots=getVolumes()(), - filetypes=c('', 'txt'),defaultPath = "" ) - - # observeEvent(input$outFolder, { - # if (!is.null(input$dir)) { - # dir_path <- input$dir - # if (!file.exists(dir_path)) { - # dir.create(dir_path) - # showModal(modalDialog( - # title = "Folder Created", - # "The folder has been created.", - # easyClose = TRUE - # )) - # } - # } - # } - # ) - + defaultPath = "/" ) + # set a default value + global<-reactiveValues(datapath = "/tmp") + # get what the interface outputs (nothing before user action) and put it in a reactive value outFolder<-reactive(input$outFolder) - output$outFolder<-renderText({gsub("//","/",parseDirPath(roots=getVolumes()(), selection=outFolder()))}) - output$configJSON<-renderText({geoClimateConfigFile( - outFile="", wf="osm", - outFolder=gsub("//","/",parseDirPath(roots=getVolumes()(), selection=outFolder())), - locations=input$location, + output$outFolder<-renderText({ + global$datapath + }) + # Now when the user sets the value in the interface : + observeEvent(ignoreNULL = TRUE, + eventExpr = { + input$outFolder + }, + handlerExpr = { + if (!"path" %in% names(dir())) return() + home <- normalizePath("~") + global$datapath <- + file.path(home, paste(unlist(outFolder()$path[-1]), collapse = .Platform$file.sep)) + }) + + # output$outFolder<-renderText({gsub("//","/",parseDirPath(roots=getVolumes()(), selection=outFolder()))}) + + + + shinyFiles::shinyDirChoose(input, id="inBDTfolder", roots=c(getVolumes()(),"~"), defaultPath = "/tmp" ) + + output$configJSON<-renderText({ + geoClimateConfigFile( + outFile = "", wf = "OSM", + outFolder = gsub("//","/", parseDirPath(roots=getVolumes()(), selection = outFolder())), + locations = input$location, rsuIndics = c("LCZ","TEB","UTRF"),gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT", "WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION","IMPERVIOUS_FRACTION","LCZ_PRIMARY", - "LCZ_FRACTION","UTRF"))}) + "LCZ_FRACTION","UTRF")) + }) From 1b33758d6d5e53865b060d97ce2284e88231848e Mon Sep 17 00:00:00 2001 From: MGousseff Date: Thu, 12 Oct 2023 18:23:49 +0200 Subject: [PATCH 08/18] commit geoCmlimateConfigFile for the 10th time, as it seems uncommited it won't be seen by app.R --- R/geoClimateConfigFile.R | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R index fa00d05..5fa13bd 100644 --- a/R/geoClimateConfigFile.R +++ b/R/geoClimateConfigFile.R @@ -97,7 +97,7 @@ outFolder<-list(folder=unbox(outFolder)) ) -listJSON = list(input=input,output=outFolder,parameters=parameters) #description=unbox(description), +listJSON <- list(input=input,output=outFolder,parameters=parameters) #description=unbox(description), output<-toJSON(x=listJSON, pretty=TRUE) @@ -111,10 +111,3 @@ return(output) } -# library(jsonlite) -# test<-geoClimateConfigFile(outFile="", wf="BDTOPO_V2.2",outFolder="/tmp",locations="Allaire", -# rsuIndics = c("LCZ","TEB","UTRF"), -# gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", -# "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) -# test - From dc0d3c952eb5583574cc84d3ed0e15fe255769ac Mon Sep 17 00:00:00 2001 From: MGousseff Date: Fri, 13 Oct 2023 10:20:50 +0200 Subject: [PATCH 09/18] Done : outFolder fed to geoClimateFile but the default value parameter not fixed yet --- R/shinyGC/app.R | 98 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 31 deletions(-) diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R index a064c80..a271b9c 100644 --- a/R/shinyGC/app.R +++ b/R/shinyGC/app.R @@ -15,20 +15,25 @@ ui <- fluidPage( sidebarPanel( shinyDirButton(id = "outFolder", label = "Output folder for GeoClimates results", - title = "Select the folder where GeoClimates will output its results", FALSE), + title = "Select the folder where GeoClimates will output its results"), + selectInput(inputId="wf", label="Workflow", choices = list(OpenStreetMap="OSM","BD TOPO V2"="BDTOPO_V2.2","BD TOPO V3"="BDTOPO_V3"), selected=list(OpenStreetMap="OSM")), + conditionalPanel( condition='input.wf!="OSM"', - shinyDirButton("inBDTfolder", + shinyDirButton("BDTinFolder", label = "BD_TOPO folder", - title = "Choose in which folder are the BD_TOPO files"), + title = "Choose in which folder are the BD_TOPO files",FALSE), numericInput(inputId="inseeCode", label="Enter Insee code of your location (town)", value = "29031") ), - textInput(inputId="location",label="Enter your locations here", - value="Redon",placeholder="A town name or some coordinates") + conditionalPanel( + condition='input.wf=="OSM"', + textInput(inputId="location",label="Enter your locations here", + value="Redon",placeholder="A town name or some coordinates") + ) ), # Main panel for displaying outputs ---- @@ -45,46 +50,77 @@ ui <- fluidPage( # Define server logic required to draw a histogram ---- server <- function(input, output) { - - - # Choose the folder where results of geoclimate will be put +# Choose the folder where results of geoclimate will be put # set the path to the button in the interface (input outfolder) - shinyFiles::shinyDirChoose(input, 'outFolder', roots=getVolumes()(), - defaultPath = "/" ) + # set a default value - global<-reactiveValues(datapath = "/tmp") + # global<-reactiveValues(datapath = "/tmp") # get what the interface outputs (nothing before user action) and put it in a reactive value - outFolder<-reactive(input$outFolder) + # outFolder<-reactive(input$outFolder) - output$outFolder<-renderText({ - global$datapath - }) - # Now when the user sets the value in the interface : - observeEvent(ignoreNULL = TRUE, - eventExpr = { - input$outFolder - }, - handlerExpr = { - if (!"path" %in% names(dir())) return() - home <- normalizePath("~") - global$datapath <- - file.path(home, paste(unlist(outFolder()$path[-1]), collapse = .Platform$file.sep)) - }) + # output$outFolder<-renderText({ + # global$datapath + # }) + + shinyFiles::shinyDirChoose(input, 'outFolder', roots=getVolumes()(), + defaultPath = "", allowDirCreate = TRUE ) + # observe({ + # cat("\ninput$outFolder value:\n\n") + # print(input$outFolder)}) + # Now when the user sets the value in the interface : (I'm a script kiddie, got this on SO and do not fully understand it now, shame to be corrected + # observeEvent(ignoreNULL = TRUE, + # eventExpr = { + # input$outFolder + # }, + # handlerExpr = { + # if (!"path" %in% names(dir())) return() + # home <- normalizePath("~") + # global$datapath <- + # file.path(home, paste(unlist(outFolder()$path[-1]), collapse = .Platform$file.sep)) + # }) - # output$outFolder<-renderText({gsub("//","/",parseDirPath(roots=getVolumes()(), selection=outFolder()))}) - + outFolder<-reactive({ + parseDirPath(roots=getVolumes()(), selection=input$outFolder) }) + # output$outFolder<- renderText({ gsub("//","/", outFolder()) }) - shinyFiles::shinyDirChoose(input, id="inBDTfolder", roots=c(getVolumes()(),"~"), defaultPath = "/tmp" ) + observe({ + cat("outFolder value:\n\n") + print( gsub("//","/", outFolder()))}) + # + # shinyFiles::shinyDirChoose(input, id="BDTinFolder", roots=c(getVolumes()(),"~"), defaultPath = "/" ) + # BDTinFolder<-reactive(input$BDTinFolder) + # global2<-reactiveValues(datapath = "/tmp") + # + # output$BDTinFolder<-renderText({ + # global2$datapath + # }) + # observeEvent(ignoreNULL = TRUE, + # eventExpr = { + # input$BDTinFolder + # }, + # handlerExpr = { + # if (!"path" %in% names(dir())) return() + # home <- normalizePath("~") + # global2$datapath <- + # file.path(home, paste(unlist(BDTinFolder()$path[-1]), collapse = .Platform$file.sep)) + # }) + # + # + # output$BDTinFolder<-renderText({gsub("//","/",parseDirPath(roots=getVolumes()(), selection=BDTinFolder()))}) + # output$configJSON<-renderText({ geoClimateConfigFile( - outFile = "", wf = "OSM", - outFolder = gsub("//","/", parseDirPath(roots=getVolumes()(), selection = outFolder())), + outFile = "", wf = input$wf, + outFolder = gsub("//","/", outFolder()), locations = input$location, rsuIndics = c("LCZ","TEB","UTRF"),gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT", "WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION","IMPERVIOUS_FRACTION","LCZ_PRIMARY", "LCZ_FRACTION","UTRF")) + #, + # BDTinseeCode = input$inseeCode, + # BDTinFolder= gsub("//","/", parseDirPath(roots=getVolumes()(), selection = BDTinFolder()))) }) From cfff859fe89174a57821975587ec95e07f778e26 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Fri, 13 Oct 2023 18:47:13 +0200 Subject: [PATCH 10/18] Shiny interface now allows to create your configuration file (some les frequently used parameters are still to be added), to choose where your geoclimate jar file is, and to run it on the config file you've created. TODO : - add unit tests for geoClimateConfigFile and geoClimateCall functions - add a tab to visualize the output (and compare to OSM map on the same zone) - add a tab to compare two outputs --- R/geoClimateCall.R | 32 ++--- R/geoClimateConfigFile.R | 97 +++++++++------ R/shinyGC/app.R | 228 ++++++++++++++++++++++-------------- man/geoClimateCall.Rd | 36 ++++++ man/geoClimateConfigFile.Rd | 80 +++++++++++++ 5 files changed, 333 insertions(+), 140 deletions(-) create mode 100644 man/geoClimateCall.Rd create mode 100644 man/geoClimateConfigFile.Rd diff --git a/R/geoClimateCall.R b/R/geoClimateCall.R index a431a35..1a3df33 100644 --- a/R/geoClimateCall.R +++ b/R/geoClimateCall.R @@ -26,19 +26,19 @@ geoClimateCall<-function(jarFilePath,configFilePath,wf="OSM") { } -test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Allaire", - rsuIndics = c("LCZ","TEB","UTRF"), - gridIndics = c("BUILDING_FRACTION", - "BUILDING_HEIGHT", - "WATER_FRACTION", - "VEGETATION_FRACTION", - "ROAD_FRACTION", - "IMPERVIOUS_FRACTION", - "LCZ_PRIMARY", - "LCZ_FRACTION", - "UTRF")) - - geoClimateCall( - jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", - configFilePath="/tmp/Redonosm.json",w="osm") - test \ No newline at end of file +# test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Allaire", +# rsuIndics = c("LCZ","TEB","UTRF"), +# gridIndics = c("BUILDING_FRACTION", +# "BUILDING_HEIGHT", +# "WATER_FRACTION", +# "VEGETATION_FRACTION", +# "ROAD_FRACTION", +# "IMPERVIOUS_FRACTION", +# "LCZ_PRIMARY", +# "LCZ_FRACTION", +# "UTRF")) +# +# geoClimateCall( +# jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", +# configFilePath="/tmp/Redonosm.json",w="osm") +# test \ No newline at end of file diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R index 5fa13bd..b911dba 100644 --- a/R/geoClimateConfigFile.R +++ b/R/geoClimateConfigFile.R @@ -19,20 +19,21 @@ #' "VEGETATION_FRACTION", #' "ROAD_FRACTION", #' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF") -#' @param outDir is the folder were the resulting JSON file will be put, the folder where GeoClimate will read it from +#' @param outConfigDir is the folder were the resulting JSON file will be put, the folder where GeoClimate will read it from #' (different from out outFolder, where GeoClimates will put its geoJSON ouputs), default is "/tmp" -#' @param outFile is the name of your configuration file, if anb empty string, a name woill be created from location +#' @param outConfigFile is the name of your configuration file, if anb empty string, a name woill be created from location #' and workflow parameters. +#' @param forceSRID some BD TOPO input file may not have an srid, this forces srid to be 2154 #' @importFrom jsonlite unbox toJSON #' @return returns a JSON configuration file to be fed to GeoClimate #' @export #' @examples -#' test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", +#' test<-geoClimateConfigFile(outConfigFile="", wf="osm",outFolder="/tmp",locations="Redon", #' rsuIndics = c("LCZ","TEB","UTRF"), #' gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", #' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) #' test -geoClimateConfigFile<-function(locations, wf, +geoClimateConfigFile<-function(wf,locations,forceSRID=FALSE, outFolder="/tmp", rsuIndics=c("LCZ","TEB","UTRF"), svSimplified = TRUE, @@ -50,36 +51,56 @@ geoClimateConfigFile<-function(locations, wf, "LCZ_PRIMARY", "LCZ_FRACTION", "UTRF"), - outDir = "/tmp", - outFile="", - BDTinFolder="",BDTinseeCode=29301) { - print(wf) - + outConfigDir = "/tmp", + outConfigFile="configFile", + BDTinFolder="",BDTinseeCode=29301, + writeNow=FALSE) { description<-"Test de description unique" - # if (wf=="OSM"){description<-"Processing OSM data"} else { - # if (wf=="BDTOPO_V2.2") {description<-"Processing BDTopo v2 data"} else { - # if (wf=="BDTOPO_V3") { - # description<-"Processing BDTopo v2 data"} - # else { description<-paste0("Processing on an unrecognized workflow: ", wf) - # } - # } - # } - - - -# description<-list(description = description) -# input<-list(input=list(locations=locations)) + if (wf=="OSM"){description<-"Processing OSM data"} else { + if (wf=="BDTOPO_V2.2") {description<-"Processing BDTopo v2 data"} else { + if (wf=="BDTOPO_V3") { + description<-"Processing BDTopo v3 data"} + else { description<-paste0("Processing on an unrecognized workflow: ", wf) + } + } + } -outFolder<-list(folder=unbox(outFolder)) +outFolder<-tryCatch( # This hideous tryCatch deals with weird shinyDirChoose behavior + { + list(folder=unbox(outFolder))}, + error=function(e){ + list(folder="\tmp") + } +) -# if (wf == "osm"){ - input=list(locations=locations) -# } else {if (grep("BDT",wf)) { -# input=list(folder=BDTinFolder,locations=BDTinseeCode) -# } -# } +if (wf == "OSM"){ + input<-list(locations=locations) + } else { if (grep("BDT",wf)==1) { + if (forceSRID==FALSE){ + input<- + list( + folder= tryCatch( + unbox(BDTinFolder), + error=function(e){ + list(folder="\tmp") + }), + locations=BDTinseeCode + ) + } else { if (forceSRID==TRUE) { + input<- + list( + folder= tryCatch( + unbox(BDTinFolder), + error=function(e){ + list(folder="\tmp") + }) + , + locations=BDTinseeCode, + srid=unbox(2154)) + }} + }} @@ -97,17 +118,27 @@ outFolder<-list(folder=unbox(outFolder)) ) -listJSON <- list(input=input,output=outFolder,parameters=parameters) #description=unbox(description), +listJSON <- list(description=unbox(description), input=input,output=outFolder,parameters=parameters) output<-toJSON(x=listJSON, pretty=TRUE) + -if (outFile=="") { outFile=paste0(locations,wf) } +if (outConfigFile=="") { outConfigFile<-paste0(locations,wf) } -write(output,file=paste0(outDir,"/",outFile,".json")) - +if (writeNow == TRUE){ + write(output,file=paste0(outConfigDir,"/",outConfigFile,".json")) +} + return(output) } +# +# library(jsonlite) +# test<-geoClimateConfigFile(outConfigFile="", wf="BDTOPO_V2.2",outFolder=list(folder="/tmp",srid=2154),locations="Allaire", +# rsuIndics = c("LCZ","TEB","UTRF"), +# gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", +# "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) +# test diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R index a271b9c..7ec09c4 100644 --- a/R/shinyGC/app.R +++ b/R/shinyGC/app.R @@ -1,130 +1,176 @@ library(shiny) library(shinyFiles) library(lczexplore) +library(magrittr) # Define UI for app that draws a histogram ---- ui <- fluidPage( - - # App title ---- - titlePanel("Run Geoclimate on OSM Data"), + + tabsetPanel( + + tabPanel("Create your GeoClimate configuration JSON file", # Sidebar layout with input and output definitions ---- - sidebarLayout( + sidebarLayout( # Sidebar panel for inputs ---- - sidebarPanel( - shinyDirButton(id = "outFolder", + sidebarPanel( + shinyDirButton(id = "outFolder", label = "Output folder for GeoClimates results", title = "Select the folder where GeoClimates will output its results"), - selectInput(inputId="wf", label="Workflow", - choices = list(OpenStreetMap="OSM","BD TOPO V2"="BDTOPO_V2.2","BD TOPO V3"="BDTOPO_V3"), + selectInput(inputId="wf", label="Workflow", + choices = list(OpenStreetMap="OSM","BD TOPO V2"="BDTOPO_V2","BD TOPO V3"="BDTOPO_V3"), selected=list(OpenStreetMap="OSM")), - conditionalPanel( - condition='input.wf!="OSM"', - shinyDirButton("BDTinFolder", + conditionalPanel( + condition='input.wf!="OSM"', + shinyDirButton("BDTinFolder", label = "BD_TOPO folder", title = "Choose in which folder are the BD_TOPO files",FALSE), - numericInput(inputId="inseeCode", label="Enter Insee code of your location (town)", value = "29031") - ), + checkboxInput("forceSRID",label="Force SRID of BD TOPO inputs to 2154",value=FALSE), + textInput(inputId="inseeCode", label="Enter Insee code of your location (town)", value = "29031") + ), - conditionalPanel( - condition='input.wf=="OSM"', - textInput(inputId="location",label="Enter your locations here", - value="Redon",placeholder="A town name or some coordinates") - ) - ), + conditionalPanel( + condition='input.wf=="OSM"', + textInput(inputId="location",label="Enter your locations here", + value="Allaire",placeholder="A town name or some coordinates") + ), - # Main panel for displaying outputs ---- - mainPanel( - titlePanel(title="Here is the content of the JSON configuration file you are building"), + checkboxGroupInput(inputId="rsuIndics",label = "Choose the indicators to compute at RSU scale", + choices=c("LCZ","TEB","UTRF"),selected=c("LCZ")), + + checkboxGroupInput(inputId="gridIndics",label = "Choose the indicators to compute at grid scale", + choices=c("BUILDING_FRACTION", + "BUILDING_HEIGHT", + "WATER_FRACTION", + "VEGETATION_FRACTION", + "ROAD_FRACTION", + "IMPERVIOUS_FRACTION", + "LCZ_FRACTION"), + selected=c("BUILDING_FRACTION" + )), + shinyDirButton("configDirOut", + label = "Folder to export config File", + title = "Choose in which folder to export the config file",FALSE), + textInput(inputId="configOutFile", + label="Name your configuration file (without extension)", + value=""), + actionButton(inputId="writeConfigFile",label="Export your parameters to JSON config File") + ) - verbatimTextOutput("configJSON"), - verbatimTextOutput("outFolder", placeholder = TRUE) - ) + + , + # Main panel for displaying outputs ---- + mainPanel( + titlePanel(title="Here is the content of the JSON configuration file you are building"), + + verbatimTextOutput("configJSON"), + + ) + ) + ), + + tabPanel("Call the system to launch Geoclimate with your configuration file and parameters", + + shinyFilesButton(id="jarFile",title="Path to geoclimate jarfile", + label="Path to geoclimate jarfile", + multiple=FALSE,filters=list("jar files"=c("jar"))), + + actionButton(inputId="runGC",label="run GeoClimate with these parameters"), + verbatimTextOutput("outMessage", placeholder = TRUE) + ) ) ) - # Define server logic required to draw a histogram ---- -server <- function(input, output) { +server <- function(input, output,session) { # Choose the folder where results of geoclimate will be put - # set the path to the button in the interface (input outfolder) - - # set a default value - # global<-reactiveValues(datapath = "/tmp") - # get what the interface outputs (nothing before user action) and put it in a reactive value - # outFolder<-reactive(input$outFolder) - - # output$outFolder<-renderText({ - # global$datapath - # }) shinyFiles::shinyDirChoose(input, 'outFolder', roots=getVolumes()(), + defaultPath = "", allowDirCreate = TRUE ) + outFolder<-reactive({ + parseDirPath(roots=getVolumes()(), selection=input$outFolder) }) + + shinyFiles::shinyDirChoose(input, id="BDTinFolder", roots=getVolumes()(), defaultPath = "" ) + + BDTinFolder<-reactive({ + BDTinFolder<-gsub( + "//","/", parseDirPath(roots=getVolumes()(), + selection = input$BDTinFolder)) + print(BDTinFolder) + }) + + # prepare export of configuration file + + shinyFiles::shinyDirChoose(input, 'configDirOut', roots=getVolumes()(), defaultPath = "", allowDirCreate = TRUE ) - # observe({ - # cat("\ninput$outFolder value:\n\n") - # print(input$outFolder)}) - # Now when the user sets the value in the interface : (I'm a script kiddie, got this on SO and do not fully understand it now, shame to be corrected - # observeEvent(ignoreNULL = TRUE, - # eventExpr = { - # input$outFolder - # }, - # handlerExpr = { - # if (!"path" %in% names(dir())) return() - # home <- normalizePath("~") - # global$datapath <- - # file.path(home, paste(unlist(outFolder()$path[-1]), collapse = .Platform$file.sep)) - # }) + configOutFolder<-reactive({ + gsub( + "//","/", + parseDirPath(roots=getVolumes()(), selection=input$configDirOut) + ) + }) - outFolder<-reactive({ - parseDirPath(roots=getVolumes()(), selection=input$outFolder) }) - - # output$outFolder<- renderText({ gsub("//","/", outFolder()) }) - - observe({ - cat("outFolder value:\n\n") - print( gsub("//","/", outFolder()))}) - # - # shinyFiles::shinyDirChoose(input, id="BDTinFolder", roots=c(getVolumes()(),"~"), defaultPath = "/" ) - # BDTinFolder<-reactive(input$BDTinFolder) - # global2<-reactiveValues(datapath = "/tmp") - # - # output$BDTinFolder<-renderText({ - # global2$datapath - # }) - # observeEvent(ignoreNULL = TRUE, - # eventExpr = { - # input$BDTinFolder - # }, - # handlerExpr = { - # if (!"path" %in% names(dir())) return() - # home <- normalizePath("~") - # global2$datapath <- - # file.path(home, paste(unlist(BDTinFolder()$path[-1]), collapse = .Platform$file.sep)) - # }) - # - # - # output$BDTinFolder<-renderText({gsub("//","/",parseDirPath(roots=getVolumes()(), selection=BDTinFolder()))}) - # - output$configJSON<-renderText({ + #output$outMessage<-renderText({ BDTinFolder() }) + + output$configJSON<-renderText({ + geoClimateConfigFile( + wf = input$wf, + outFolder = gsub("//","/",outFolder()) , + locations = input$location, + forceSRID=input$forceSRID, + rsuIndics = input$rsuIndics, + gridIndics = input$gridIndics, + BDTinseeCode = input$inseeCode, + BDTinFolder= BDTinFolder(), + outConfigDir=configOutFolder(), + outConfigFile = input$configOutFile, + writeNow=FALSE) + }) + +observeEvent( + input$writeConfigFile, { geoClimateConfigFile( - outFile = "", wf = input$wf, - outFolder = gsub("//","/", outFolder()), + wf = input$wf, + outFolder = gsub("//","/",outFolder()) , locations = input$location, - rsuIndics = c("LCZ","TEB","UTRF"),gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT", - "WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION","IMPERVIOUS_FRACTION","LCZ_PRIMARY", - "LCZ_FRACTION","UTRF")) - #, - # BDTinseeCode = input$inseeCode, - # BDTinFolder= gsub("//","/", parseDirPath(roots=getVolumes()(), selection = BDTinFolder()))) - }) + forceSRID=input$forceSRID, + rsuIndics = input$rsuIndics, + gridIndics = input$gridIndics, + BDTinseeCode = input$inseeCode, + BDTinFolder= BDTinFolder(), + outConfigDir=configOutFolder(), + outConfigFile = input$configOutFile, + writeNow=TRUE) + } +) +shinyFiles::shinyFileChoose(input, 'jarFile', roots=getVolumes()(), + defaultPath = "/" ) +jarFilePath<-reactive({ + if (!is.null(input$jarFile)) { + gsub( + "//","/", + parseFilePaths(roots=getVolumes()(), input$jarFile)$datapath) + } + }) +output$outMessage<-renderText({jarFilePath()}) + +observeEvent( + input$runGC, { + geoClimateCall(jarFilePath=jarFilePath(), + configFilePath=paste0(configOutFolder(),"/",input$configOutFile,".json"), + wf=input$wf) + } +) + + } shinyApp(ui = ui, server = server) \ No newline at end of file diff --git a/man/geoClimateCall.Rd b/man/geoClimateCall.Rd new file mode 100644 index 0000000..3c3b0e0 --- /dev/null +++ b/man/geoClimateCall.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/geoClimateCall.R +\name{geoClimateCall} +\alias{geoClimateCall} +\title{Calls GeoClimate and feeds it a configuration file by building a command an using system (only tested on linux)} +\usage{ +geoClimateCall(jarFilePath, configFilePath, wf = "OSM") +} +\arguments{ +\item{jarFilePath}{tells where the geoclimate jar file is, default points to the embedded jar file, +i.e. the latest snapshot version when the package was built. +Versions can be downloaded from https://github.com/orbisgis/geoclimate/wiki/Download} + +\item{configFilePath}{points to the configuration JSON file for GeoClimate, typically a file created with the +geoClimateConfigFile function} + +\item{wf}{is the workflow to use with GeoClimate, the default is OSM for OpenStreetMap. +The other possible value is "BDTOPO_V2". Other values will be added (e.g. for BDTOPO_V3) when tested.} +} +\value{ +returns nothing but files will be created by GeoClimate in the folder specified in the +JSON configuration file. +} +\description{ +Calls GeoClimate and feeds it a configuration file by building a command an using system (only tested on linux) +} +\examples{ +test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", +rsuIndics = c("LCZ","TEB","UTRF"), +gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", +"IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) +geoClimateCall( +jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", +configFilePath="/tmp/Redonosm.json",w="osm") +test +} diff --git a/man/geoClimateConfigFile.Rd b/man/geoClimateConfigFile.Rd new file mode 100644 index 0000000..cc8dbb7 --- /dev/null +++ b/man/geoClimateConfigFile.Rd @@ -0,0 +1,80 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/geoClimateConfigFile.R +\name{geoClimateConfigFile} +\alias{geoClimateConfigFile} +\title{Builds a JSON configuration file for GeoClimate workflow} +\usage{ +geoClimateConfigFile( + wf, + locations, + forceSRID = FALSE, + outFolder = "/tmp", + rsuIndics = c("LCZ", "TEB", "UTRF"), + svSimplified = TRUE, + estimatedHeight = TRUE, + grid_x_size = 100, + grid_y_size = 100, + rowCol = FALSE, + outputType = "geojson", + gridIndics = c("BUILDING_FRACTION", "BUILDING_HEIGHT", "WATER_FRACTION", + "VEGETATION_FRACTION", "ROAD_FRACTION", "IMPERVIOUS_FRACTION", "LCZ_PRIMARY", + "LCZ_FRACTION", "UTRF"), + outConfigDir = "/tmp", + outConfigFile = "", + BDTinFolder = "", + BDTinseeCode = 29301 +) +} +\arguments{ +\item{wf}{is the workflow used by GeoClimate. For now, only osm is available, for OpenStreetMap, but bdt for +BD TOPO of IGN should be added when an online database is available.} + +\item{locations}{is either the town or the coordinates of the bounding box of the area on which GeoClimate will run. +If a town name, it will be fed to the Nominoe API, through the overpass API of OpenStreetMap.} + +\item{forceSRID}{some BD TOPO input file may not have an srid, this forces srid to be 2154} + +\item{outFolder}{indicates where the results of GeoClimate will be put} + +\item{rsuIndics}{is a vector with the indicators one wants to compute at the RSU scale. The default is c("LCZ","TEB","UTRF"),} + +\item{svSimplified}{uses the simplified method to calculate skyview factor, default = TRUE} + +\item{estimatedHeight}{uses an algorithm to esitmate the missing building height, default = TRUE} + +\item{grid_x_size}{is the x size for the grid if some grid indicators are to be computed, default=100} + +\item{grid_y_size}{is the x size for the grid if some grid indicators are to be computed, default=100} + +\item{rowCol}{if grid_x_size and grid_y_size are not set, one cal set the number of rows and cols throug rowCol, +but the recommended and defualt is FALSE} + +\item{outputType}{is the format of GeoClimate outputs, default="geojson",} + +\item{gridIndics}{is a vector containing the indicators to compute at the grid scale. Default is +c("BUILDING_FRACTION", +"BUILDING_HEIGHT", +"WATER_FRACTION", +"VEGETATION_FRACTION", +"ROAD_FRACTION", +"IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")} + +\item{outConfigDir}{is the folder were the resulting JSON file will be put, the folder where GeoClimate will read it from +(different from out outFolder, where GeoClimates will put its geoJSON ouputs), default is "/tmp"} + +\item{outConfigFile}{is the name of your configuration file, if anb empty string, a name woill be created from location +and workflow parameters.} +} +\value{ +returns a JSON configuration file to be fed to GeoClimate +} +\description{ +Builds a JSON configuration file for GeoClimate workflow +} +\examples{ +test<-geoClimateConfigFile(outConfigFile="", wf="osm",outFolder="/tmp",locations="Redon", +rsuIndics = c("LCZ","TEB","UTRF"), +gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", +"IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) +test +} From 12e6f544fe42bdafb1f8da22afdb7d3ce8b20641 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Mon, 16 Oct 2023 15:24:00 +0200 Subject: [PATCH 11/18] Shows the result once GC ran the config file. TO DO : add the OSM map for the same area. --- R/geoClimateConfigFile.R | 26 ++++++------- R/shinyGC/app.R | 80 +++++++++++++++++++++++++++++++++++----- R/showLCZ.R | 12 ++++-- 3 files changed, 93 insertions(+), 25 deletions(-) diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R index b911dba..9807341 100644 --- a/R/geoClimateConfigFile.R +++ b/R/geoClimateConfigFile.R @@ -5,7 +5,7 @@ #' BD TOPO of IGN should be added when an online database is available. #' @param outFolder indicates where the results of GeoClimate will be put #' @param rsuIndics is a vector with the indicators one wants to compute at the RSU scale. The default is c("LCZ","TEB","UTRF"), -#' @param svSimplified uses the simplified method to calculate skyview factor, default = TRUE +#' @param svfSimplified uses the simplified method to calculate skyview factor, default = TRUE #' @param estimatedHeight uses an algorithm to esitmate the missing building height, default = TRUE #' @param grid_x_size is the x size for the grid if some grid indicators are to be computed, default=100 #' @param grid_y_size is the x size for the grid if some grid indicators are to be computed, default=100 @@ -36,13 +36,13 @@ geoClimateConfigFile<-function(wf,locations,forceSRID=FALSE, outFolder="/tmp", rsuIndics=c("LCZ","TEB","UTRF"), - svSimplified = TRUE, - estimatedHeight=TRUE, - grid_x_size=100, - grid_y_size=100, - rowCol=FALSE, - outputType="geojson", - gridIndics=c("BUILDING_FRACTION", + svfSimplified = TRUE, + estimatedHeight = TRUE, + grid_x_size = 100, + grid_y_size = 100, + rowCol = FALSE, + outputType = "geojson", + gridIndics = c("BUILDING_FRACTION", "BUILDING_HEIGHT", "WATER_FRACTION", "VEGETATION_FRACTION", @@ -52,10 +52,10 @@ geoClimateConfigFile<-function(wf,locations,forceSRID=FALSE, "LCZ_FRACTION", "UTRF"), outConfigDir = "/tmp", - outConfigFile="configFile", - BDTinFolder="",BDTinseeCode=29301, - writeNow=FALSE) { - description<-"Test de description unique" + outConfigFile = "configFile", + BDTinFolder = "",BDTinseeCode=29301, + writeNow = FALSE) { + # description<-"Test de description unique" if (wf=="OSM"){description<-"Processing OSM data"} else { if (wf=="BDTOPO_V2.2") {description<-"Processing BDTopo v2 data"} else { @@ -107,7 +107,7 @@ if (wf == "OSM"){ parameters<-list( rsu_indicators = list( indicatorUse = rsuIndics, - svSimplified = unbox(svSimplified), + svSimplified = unbox(svfSimplified), estimatedHeight = unbox(estimatedHeight)), grid_indicators = list( x_size = unbox(grid_x_size), y_size = unbox(grid_y_size), diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R index 7ec09c4..f68af54 100644 --- a/R/shinyGC/app.R +++ b/R/shinyGC/app.R @@ -5,9 +5,17 @@ library(magrittr) # Define UI for app that draws a histogram ---- ui <- fluidPage( + h1(" This application helps build a configuration file to feed to geoclimate"), + h2(" The OSM workflow allows to run GeoClimate on any given city."), + h2("For BD TOPO workflows, the user has to provide a path to the input data"), + h2(" It is not possible to build a configuration files using bounding box coordinates yet."), tabsetPanel( - + ############################################ + ## + ## Tab to create the config file + ## + ############################################ tabPanel("Create your GeoClimate configuration JSON file", # Sidebar layout with input and output definitions ---- @@ -27,7 +35,7 @@ ui <- fluidPage( condition='input.wf!="OSM"', shinyDirButton("BDTinFolder", label = "BD_TOPO folder", - title = "Choose in which folder are the BD_TOPO files",FALSE), + title = "Choose in which folder are the BD_TOPO files"), checkboxInput("forceSRID",label="Force SRID of BD TOPO inputs to 2154",value=FALSE), textInput(inputId="inseeCode", label="Enter Insee code of your location (town)", value = "29031") ), @@ -40,6 +48,12 @@ ui <- fluidPage( checkboxGroupInput(inputId="rsuIndics",label = "Choose the indicators to compute at RSU scale", choices=c("LCZ","TEB","UTRF"),selected=c("LCZ")), + fluidRow( + column( width = 4, checkboxInput(inputId = "svfSimple", + label = "Use simplified algorithm for sky view factor", + value = TRUE)), + column(width = 4, checkboxInput(inputId = "EstimateHeight", label = "Estimate missing building heights", value = TRUE)) + ), checkboxGroupInput(inputId="gridIndics",label = "Choose the indicators to compute at grid scale", choices=c("BUILDING_FRACTION", @@ -51,9 +65,11 @@ ui <- fluidPage( "LCZ_FRACTION"), selected=c("BUILDING_FRACTION" )), + numericInput(inputId="xGridSize", label="Choose the x size for the grid", value = 100, min = 10, max = 1000, step = 10), + numericInput(inputId="yGridSize", label="Choose the y size for the grid", value = 100, min = 10, max = 1000, step = 10), shinyDirButton("configDirOut", label = "Folder to export config File", - title = "Choose in which folder to export the config file",FALSE), + title = "Choose in which folder to export the config file"), textInput(inputId="configOutFile", label="Name your configuration file (without extension)", value=""), @@ -63,26 +79,40 @@ ui <- fluidPage( , - # Main panel for displaying outputs ---- + # Main panel for displaying config file ---- mainPanel( titlePanel(title="Here is the content of the JSON configuration file you are building"), - verbatimTextOutput("configJSON"), + verbatimTextOutput("configJSON") + ) ) ), + ############################################ + ## + ## tab to call geoclimate and show results + ## + ############################################ tabPanel("Call the system to launch Geoclimate with your configuration file and parameters", - + sidebarLayout( + sidebarPanel( shinyFilesButton(id="jarFile",title="Path to geoclimate jarfile", label="Path to geoclimate jarfile", multiple=FALSE,filters=list("jar files"=c("jar"))), - actionButton(inputId="runGC",label="run GeoClimate with these parameters"), - verbatimTextOutput("outMessage", placeholder = TRUE) + actionButton(inputId = "runGC",label = "Run GeoClimate with these parameters"), + verbatimTextOutput("outMessage", placeholder = TRUE), + actionButton(inputId = "showPlot", label = "View the outputs once GeoClimate executed successfully ")), + mainPanel( + verbatimTextOutput("folderImport"), + plotOutput("LCZplot") + ) + ) ) + ) ) # Define server logic required to draw a histogram ---- @@ -92,7 +122,9 @@ server <- function(input, output,session) { shinyFiles::shinyDirChoose(input, 'outFolder', roots=getVolumes()(), defaultPath = "", allowDirCreate = TRUE ) outFolder<-reactive({ - parseDirPath(roots=getVolumes()(), selection=input$outFolder) }) + gsub( + "//","/", + parseDirPath(roots=getVolumes()(), selection=input$outFolder)) }) shinyFiles::shinyDirChoose(input, id="BDTinFolder", roots=getVolumes()(), defaultPath = "" ) @@ -123,6 +155,10 @@ server <- function(input, output,session) { outFolder = gsub("//","/",outFolder()) , locations = input$location, forceSRID=input$forceSRID, + svfSimplified = input$svfSimple, + estimatedHeight = input$EstimateHeight, + grid_x_size = input$xGridSize, + grid_y_size = input$yGridSize, rsuIndics = input$rsuIndics, gridIndics = input$gridIndics, BDTinseeCode = input$inseeCode, @@ -140,6 +176,8 @@ observeEvent( locations = input$location, forceSRID=input$forceSRID, rsuIndics = input$rsuIndics, + grid_x_size = input$xGridSize, + grid_y_size = input$yGridSize, gridIndics = input$gridIndics, BDTinseeCode = input$inseeCode, BDTinFolder= BDTinFolder(), @@ -169,8 +207,32 @@ observeEvent( wf=input$wf) } ) + + ############################################ + ## + ## Visualize GC outputs + ## + ############################################ + + wf<- reactive({input$wf}) + LCZpath<-reactive({if ( wf() == "OSM"){ paste0(outFolder(),"/osm_",input$location,"/") } else + if (wf() == "BDTOPO_V2") {paste0(outFolder(),"/bdtopo_2_",input$inseeCode,"/") }}) + output$folderImport<-renderText({ + LCZpath() + }) + +observeEvent( + input$showPlot,{ + sf1<-importLCZvect(dirPath=LCZpath()) + print(summary(sf1)) + LCZplot<-showLCZ(sf1) + output$LCZplot<-renderPlot({ + LCZplot + }) +}) + } shinyApp(ui = ui, server = server) \ No newline at end of file diff --git a/R/showLCZ.R b/R/showLCZ.R index af9c694..51f332e 100644 --- a/R/showLCZ.R +++ b/R/showLCZ.R @@ -15,7 +15,7 @@ #' in your dataset and colors associated to these levels when not in the standard representation. You can pas your levels through a vector and you colors through another vector called colors. #' For more details about this, read the "lcz_explore_alter" vignette. #' @import sf ggplot2 dplyr cowplot forcats grDevices -#' @return no object is returned, but plots of the LCZ levels are produced +#' @return return the plot of the LCZ levels #' @export #' @examples #' # On original LCZ levels, use the \'standard\' value for the \'repr\' argument. @@ -159,9 +159,15 @@ showLCZ<-function(sf, title="", wf="",column="LCZ_PRIMARY", ggtitle(wtitre) } - if (repr=="standard"){print(pstandard)} + if (repr=="standard"){ + print(pstandard) + return(pstandard) + } else { - if (repr=="alter"){print(palter)} + if (repr=="alter"){ + print(palter) + return(palter) + } else {stop("the repr argument must be \"standard\" or \"alter\" ")} } From 5931713ca464128404c59ef5d671870229730d0a Mon Sep 17 00:00:00 2001 From: MGousseff Date: Wed, 18 Oct 2023 14:13:26 +0200 Subject: [PATCH 12/18] rather functional shiny app to build a config file and rune GeoClimate. --- R/shinyGC/app.R | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/R/shinyGC/app.R b/R/shinyGC/app.R index f68af54..f94ffd4 100644 --- a/R/shinyGC/app.R +++ b/R/shinyGC/app.R @@ -1,7 +1,13 @@ library(shiny) library(shinyFiles) +library(ggplot2) library(lczexplore) library(magrittr) +library(osmdata) +library(sf) +#devtools::install_github("elipousson/getdata") +library(getdata) + # Define UI for app that draws a histogram ---- ui <- fluidPage( @@ -37,7 +43,7 @@ ui <- fluidPage( label = "BD_TOPO folder", title = "Choose in which folder are the BD_TOPO files"), checkboxInput("forceSRID",label="Force SRID of BD TOPO inputs to 2154",value=FALSE), - textInput(inputId="inseeCode", label="Enter Insee code of your location (town)", value = "29031") + textInput(inputId="inseeCode", label="Enter Insee code of your location (town)", value = "29162") ), conditionalPanel( @@ -104,10 +110,13 @@ ui <- fluidPage( actionButton(inputId = "runGC",label = "Run GeoClimate with these parameters"), verbatimTextOutput("outMessage", placeholder = TRUE), - actionButton(inputId = "showPlot", label = "View the outputs once GeoClimate executed successfully ")), + actionButton(inputId = "showPlot", label = "View the outputs once GeoClimate executed successfully "), + actionButton(inputId = "showSourceData", label = "View the source data used to compute the LCZ ")), + mainPanel( verbatimTextOutput("folderImport"), - plotOutput("LCZplot") + plotOutput("LCZplot"), + plotOutput("sourceDataPlot") ) ) @@ -233,6 +242,31 @@ observeEvent( }) }) +observeEvent( + input$showSourceData,{ + zone<-read_sf(paste0(LCZpath(),"zone.geojson")) + buildings<-read_sf(paste0(LCZpath(),"/building.geojson")) %>% st_intersection(zone) + roads<-read_sf(paste0(LCZpath(),"/road.geojson")) %>% st_intersection(zone) + vegetation<-read_sf(paste0(LCZpath(),"/vegetation.geojson")) %>% st_intersection(zone) + water<-read_sf(paste0(LCZpath(),"/water.geojson")) %>% st_intersection(zone) + + + + sourceDataPlot<-ggplot()+ + geom_sf(data=vegetation,aes(),fill="#bbdb7a")+ + geom_sf(data=water,aes(),fill="blue")+ + geom_sf(data=roads,aes(),fill="black")+ + geom_sf(data=buildings,aes(),fill="grey") + + + output$sourceDataPlot<-renderPlot({ + sourceDataPlot + }) + + + }) + + } shinyApp(ui = ui, server = server) \ No newline at end of file From 6ce38f7e10f6d6aa88c337ce1e03ed71aec7b5d1 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Wed, 18 Oct 2023 17:40:44 +0200 Subject: [PATCH 13/18] Examples corrected in inportLCZraster Typos corrected in paper.md Some typos corrected in the vignettes Several references added to paper.md --- .../CODE_OF_CONDUCT.md => CODE_OF_CONDUCT.md | 0 .github/CONTRIBUTING.md => CONTRIBUTING.md | 0 R/importLCZraster.R | 14 +- docs/articles/joss/paper.bib | 93 ++-- docs/articles/joss/paper.md | 439 +++++++++--------- man/importLCZraster.Rd | 4 +- vignettes/lczexplore_alter.Rmd | 2 +- vignettes/lczexplore_en.Rmd | 30 +- vignettes/lczexplore_raster_vector.Rmd | 16 +- 9 files changed, 324 insertions(+), 274 deletions(-) rename .github/CODE_OF_CONDUCT.md => CODE_OF_CONDUCT.md (100%) rename .github/CONTRIBUTING.md => CONTRIBUTING.md (100%) diff --git a/.github/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md similarity index 100% rename from .github/CODE_OF_CONDUCT.md rename to CODE_OF_CONDUCT.md diff --git a/.github/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 100% rename from .github/CONTRIBUTING.md rename to CONTRIBUTING.md diff --git a/R/importLCZraster.R b/R/importLCZraster.R index 3ff74f4..0bb3bf2 100644 --- a/R/importLCZraster.R +++ b/R/importLCZraster.R @@ -20,11 +20,21 @@ #' #' @examples #' redonBbox<-importLCZvect(dirPath=paste0(system.file("extdata", package = "lczexplore"), -#' "/bdtopo_2_2/Redon"), file="rsu_lcz.geojson",column="LCZ_PRIMARY", output="bBox") +#' "/bdtopo_2_2/Redon"), file="rsu_lcz.geojson", column="LCZ_PRIMARY", output="bBox") #' #' redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), #' fileName="redonWudapt.tif",bBox=redonBbox) #' +#' # another way to get the bounding box when one explores a given city would be the use of the +#' # getbb() function from the osmdata package. +#' # This exaample requires the osmdata package and therefore is not executed here +#' # redonBbox<-osmdata::getbb("Redon") +#' # redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), +#' # fileName="redonWudapt.tif",bBox=redonBbox) +#' +#' # another way to get the bounding box when one doesn't want to compare to a vector map is to enter it's coordinates +#' # and feed them to st_bbox() of the sf package. +#' #' # the following example can only be executed when user has downloaded #' # CONUS-wide LCZ map and Training Areas on WUDAPT website #' # sanDiegobBoxCoord<-st_sf(a=1:2, geom=st_sfc( @@ -37,7 +47,7 @@ #' #fileName="CONUS_LCZ_map_NLCD_v1.0_epsg4326.tif", #' #column="CONUS_LCZ_map_NLCD_v1.0_epsg4326" #' # ,bBox=sanDiegoBbox) -#' #showLCZ(sanDiegoWudapt,column="CONUS_LCZ_map_NLCD_v1.0_epsg4326") +#' #showLCZ(sanDiegoWudapt, column="CONUS_LCZ_map_NLCD_v1.0_epsg4326") importLCZraster<-function(dirPath,zone="europe",bBox,fileName="EU_LCZ_map.tif", column='EU_LCZ_map', typeLevels=c("1"="1","2"="2","3"="3","4"="4","5"="5","6"="6","7"="7","8"="8", "9"="9","10"="10","101"="11","102"="12","103"="13","104"="14", diff --git a/docs/articles/joss/paper.bib b/docs/articles/joss/paper.bib index a8f08a7..3d680f3 100644 --- a/docs/articles/joss/paper.bib +++ b/docs/articles/joss/paper.bib @@ -154,36 +154,36 @@ @article{chingWUDAPTUrbanWeather2018a issn = {0003-0007, 1520-0477}, doi = {10.1175/BAMS-D-16-0236.1}, urldate = {2023-06-30}, - } - - @article{cohenCoefficientAgreementNominal1960, - title = {A {{Coefficient}} of {{Agreement}} for {{Nominal Scales}}}, - author = {Cohen, Jacob}, - year = {1960}, - month = apr, - journal = {Educational and Psychological Measurement}, - volume = {20}, - number = {1}, - pages = {37--46}, - issn = {0013-1644, 1552-3888}, - doi = {10.1177/001316446002000104}, - urldate = {2023-06-30}, - langid = {english} - } - - @article{demuzereLCZGeneratorWeb2021, - title = {{{LCZ Generator}}: {{A Web Application}} to {{Create Local Climate Zone Maps}}}, - shorttitle = {{{LCZ Generator}}}, - author = {Demuzere, Matthias and Kittner, Jonas and Bechtel, Benjamin}, - year = {2021}, - month = apr, - journal = {Frontiers in Environmental Science}, - volume = {9}, - pages = {637455}, - issn = {2296-665X}, - doi = {10.3389/fenvs.2021.637455}, - urldate = {2023-06-30}, - } +} + +@article{cohenCoefficientAgreementNominal1960, + title = {A {{Coefficient}} of {{Agreement}} for {{Nominal Scales}}}, + author = {Cohen, Jacob}, + year = {1960}, + month = apr, + journal = {Educational and Psychological Measurement}, + volume = {20}, + number = {1}, + pages = {37--46}, + issn = {0013-1644, 1552-3888}, + doi = {10.1177/001316446002000104}, + urldate = {2023-06-30}, + langid = {english} +} + +@article{demuzereLCZGeneratorWeb2021, + title = {{{LCZ Generator}}: {{A Web Application}} to {{Create Local Climate Zone Maps}}}, + shorttitle = {{{LCZ Generator}}}, + author = {Demuzere, Matthias and Kittner, Jonas and Bechtel, Benjamin}, + year = {2021}, + month = apr, + journal = {Frontiers in Environmental Science}, + volume = {9}, + pages = {637455}, + issn = {2296-665X}, + doi = {10.3389/fenvs.2021.637455}, + urldate = {2023-06-30}, +} @techreport{bernardGenericAlgorithmAutomatically2023, type = {Preprint}, @@ -235,4 +235,37 @@ @article{RJ-2018-009 pages = {439--446}, volume = {10}, number = {1} +} + + +@article{demuzere2019mapping, + title={Mapping Europe into local climate zones}, + author={Demuzere, Matthias and Bechtel, Benjamin and Middel, Ariane and Mills, Gerald}, + journal={PloS one}, + volume={14}, + number={4}, + pages={e0214474}, + year={2019}, + publisher={Public Library of Science San Francisco, CA USA} +} + +@article{demuzere2022global, + title={A global map of Local Climate Zones to support earth system modelling and urban scale environmental science}, + author={Demuzere, Matthias and Kittner, Jonas and Martilli, Alberto and Mills, Gerald and Moede, Christian and Stewart, Iain D and van Vliet, Jasper and Bechtel, Benjamin}, + journal={Earth System Science Data Discussions}, + volume={2022}, + pages={1--57}, + year={2022}, + publisher={G{\"o}ttingen, Germany} +} + +@article{demuzere2020combining, + title={Combining expert and crowd-sourced training data to map urban form and functions for the continental US}, + author={Demuzere, Matthias and Hankey, Steve and Mills, Gerald and Zhang, Wenwen and Lu, Tianjun and Bechtel, Benjamin}, + journal={Scientific data}, + volume={7}, + number={1}, + pages={264}, + year={2020}, + publisher={Nature Publishing Group UK London} } \ No newline at end of file diff --git a/docs/articles/joss/paper.md b/docs/articles/joss/paper.md index a994b7d..982d00d 100644 --- a/docs/articles/joss/paper.md +++ b/docs/articles/joss/paper.md @@ -1,59 +1,61 @@ --- -title: 'lczexplore : an R package to explore Local Climate Zone classifications' +title: 'lczexplore: an R package to explore Local Climate Zone classifications' tags: -- R SOFTWARE -- climate -- environment -- GIS -- spatial analysis -- cities - + - R SOFTWARE + - climate + - environment + - GIS + - spatial analysis + - cities + authors: - -- name: Matthieu Gousseff - orcid: 0000-0002-7106-2677 - equal-contrib: true - affiliation: 1 -- name: Erwan Bocher - orcid : 0000-0002-4936-7079 - equal-contrib: true - affiliation: 1 -- name: Jérémy Bernard - orcid : 0000-0001-7374-5722 - corresponding: true # (This is how to denote the corresponding author) - affiliation: "1, 2, 4" -- name: Elisabeth Le Saux Wiederhold - orcid: - corresponding: true - affiliation: 3 + + - name: Matthieu Gousseff + orcid: 0000-0002-7106-2677 + equal-contrib: true + affiliation: 1 + - name: Erwan Bocher + orcid: 0000-0002-4936-7079 + equal-contrib: true + affiliation: 1 + - name: Jérémy Bernard + orcid: 0000-0001-7374-5722 + corresponding: true # (This is how to denote the corresponding author) + affiliation: "1, 2, 4" + - name: Elisabeth Le Saux Wiederhold + orcid: + corresponding: true + affiliation: 3 affiliations: - -- name: CNRS, Lab-STICC, UMR 6285, Vannes, France - index: 1 -- name: University of Savoie Mont-Blanc, LOCIE, UMR 5271, France - index: 2 -- name: Université Bretagne Sud, Lab-STICC, UMR 6285, Vannes, France - index: 3 -- name : University of Gothenburg, Department of Earth Sciences, Sweden - index: 4 + + - name: CNRS, Lab-STICC, UMR 6285, Vannes, France + index: 1 + - name: University of Savoie Mont-Blanc, LOCIE, UMR 5271, France + index: 2 + - name: Université Bretagne Sud, Lab-STICC, UMR 6285, Vannes, France + index: 3 + - name: University of Gothenburg, Department of Earth Sciences, Sweden + index: 4 bibliography: paper.bib date: 01 april 2023 -editor_options: - markdown: +editor_options: + markdown: wrap: sentence --- # Summary -Climate change is a growing concern for city planners as Urban Heat Islands have an impact on mortality [@clarke1972some], -health in general [@lowe2016energy] and consumption of energy for building cooling [@malys2012microclimate] among other effects. -A first step towards large scale study of urban climate is to define classes based on logical division of the landscape, +Climate change is a growing concern for city planners as Urban Heat Islands have an impact on +mortality [@clarke1972some], health in general [@lowe2016energy] and consumption of energy +for building cooling [@malys2012microclimate] among other effects. +A first step towards large scale study of urban climate is to define classes +based on logical division of the landscape, such as Local Climate Zones (LCZ) defined by [@stewart2012local]. -The lczexplore package aims at comparing different LCZ classifications, +The lczexplore package aims at comparing different LCZ classifications, but can be used to compare any pair of classifications on geographical units. -A spatial comparison is performed by producing agreement maps between classifications, agreement statistics and +A spatial comparison is performed by producing agreement maps between classifications, agreement statistics and a confusion matrix to help qualify and quantify the misclassifications. This software is available as a free and opensource R package. @@ -61,95 +63,100 @@ This software is available as a free and opensource R package. # Statement of need ## Comparing maps -As stated in [@visser2006map] comparing map is an important issue in environmental research. -The four main reasons to compare categorical variables on geographical units are: -- to assess the differences between maps generated by models under different scenarios and assumptions, -- to detect temporal changes, -- to calibrate or validate models, -- to perform uncertainty and sensitivity analysis. +As stated in [@visser2006map] comparing maps is an important issue in environmental research. +The four main reasons to compare categorical variables on geographical units are: +- to assess the differences between maps generated by models under different scenarios and assumptions, +- to detect temporal changes, +- to calibrate or validate models, +- to perform uncertainty and sensitivity analysis. -## Comparing specifically LCZ maps +## Comparing specifically LCZ maps Climate change is a growing concern for city planners with a special focus on Urban Heat Island phenomenons. -The terms *rural* and *urban* lack of a clear definition and different classifications +The terms *rural* and *urban* lack of a clear definition and different classifications of urban and rural landscapes were proposed. Stewart and Oke [@stewart2012local] defined an approach that complies with [@grigg1965logic] criteria of geographical classification. -Their Local Climate Zones (LCZ) are based on a logical segmentation of land-use and urban canopy parameters +Their Local Climate Zones (LCZ) are based on a logical segmentation of land-use and urban canopy parameters and define 10 urban types and 7 land cover types. -LCZ have gained popularity in the past decade as they sum up relevant information and can help, for instance, +LCZ have gained popularity in the past decade as they sum up relevant information and can help, for instance, apprehend the intensity of the Urban Heat Island [@kotharkar2018evaluating]. Several methods aim to classify a territory into LCZ, but only few workflows allow an automatic classification for any given area. -[@quan2021systematic] distinguishes two main streams of production of these LCZ: -- the raster stream processes remotely sensed information, and applies machine learning -algorithms trained using local experts' knowledge. For instance, the WUDAPT platform produced -LCZ maps of Europe and North-America this way [@chingWUDAPTUrbanWeather2018a]. -- the vector stream uses Geographic Information System (GIS) layers that represent the main topographic features, -defines spatial units, computes urban canopy parameters and uses them to classify spatial units into LCZ. -For instance, the GeoClimate geospatial toolbox produces LCZ classifications -from OpenStreetMap or french BDTopo data [@bocher2021geoclimate]. +[@quan2021systematic] distinguishes two main streams of production of these LCZ: +- the raster stream processes remotely sensed information, and applies machine learning + algorithms trained using local experts' knowledge. In this way, the WUDAPT community [@chingWUDAPTUrbanWeather2018a] + produced thousands of city-based LCZ maps (accessible via the LCZ Generator ([@demuzereLCZGeneratorWeb2021])) + but also large-scale maps for Europe, the continental United States and the whole world ([@demuzere2019mapping], + [@demuzere2020combining], [@demuzere2022global]). +- the vector stream uses Geographic Information System (GIS) layers that represent the main topographic features, + defines spatial units, computes urban canopy parameters and uses them to classify spatial units into LCZ. + For instance, the GeoClimate geospatial toolbox produces LCZ classifications + from OpenStreetMap or french BDTopo data [@bocher2021geoclimate]. The existence of several methods to produce LCZ classifications, or the use of a method with different input data, raises the need for a tool to quickly get: 1. Statistics measuring the general agreement between two classifications -2. A spatial representation to allow a fast visual assessment of the zones -where the classifications agree or disagree. -3. A confusion matrix, to explore how the levels of one classification break up -in levels of the other classification, shown in a graphical way to help visualize the -main differences between the classifications. +2. A spatial representation to allow a fast visual assessment of the zones + where the classifications agree or disagree. +3. A confusion matrix, to explore how the levels of one classification break up + in levels of the other classification, shown in a graphical way to help visualize the + main differences between the classifications. # State of the field and feature comparison ## State of the field on spatial classification comparison -The question of going beyond the simple visual observation of differences between maps is not a new one. -A first approach would be, on raster maps, to simply compute the agreement between two maps as the proportion -of pixels for which the two maps have the same value of the variable of interest. +The question of going beyond the simple visual observation of differences between maps is not a new one. +A first approach would be, on raster maps, to simply compute the agreement between two maps as the proportion +of pixels for which the two maps have the same value of the variable of interest. This approach is often sufficient to help specialists compare pairs of -maps, but it has two main drawbacks +maps, but it has two main drawbacks: - - two totally random maps won't have a value of agreement of zero, as some pixel values may agree by chance, - - only raster maps where pixels match perfectly (same size, not translated) can be treated, or -some pre-treatment are needed (like nearest neighbour interpolation for instance). +- two totally random maps won't have a value of agreement of zero, as some pixel values may agree by chance, +- only raster maps where pixels match perfectly (same size, not translated) can be treated, or + some pre-treatment are needed (like nearest neighbour interpolation for instance). -To prevent the first drawback, [@monserudComparingGlobalVegetation1992] +To prevent the first drawback, [@monserudComparingGlobalVegetation1992] proposed the use of Cohen's kappa coefficient of agreement for nominal scales [@cohenCoefficientAgreementNominal1960]. -Each pixel is seen as an individual to which each map assigns a value of a categorical variable -(each map is seen as a "rater"). +Cohen's Kappa allow to assess how two raters agree or differ in the task of rating individual. +In our case, each pixel is seen as an individual, each map is seen as a rater and the value of the raster at each pixel +is seen as the rate. -The comprehensive Map Comparison kit, which was released in 2001 by the -Netherlands Environmental Assessment Agency [@visser2006map], is an example of tool -that allows multiple methods to compare raster maps. It includes a fuzzy algorithm which allows to tackle small -shifts of one map from another. It only works on raster maps, only on Windows OS and -doesn't allow automation for several pairs of maps. +The comprehensive Map Comparison kit, which was released in 2001 by the +Netherlands Environmental Assessment Agency [@visser2006map], is an example of a tool +that provides multiple methods to compare raster maps. It includes a fuzzy algorithm which allows to tackle small +shifts of one map from another. It only works on raster maps, only on Windows OS and +doesn't allow automation for several pairs of maps. -To tackle the second drawback, one can rasterize vector files, for instance by applying a raster grid -to a vector layer and assign, for instance, the value whose area is the most present in the pixel. -This can produce severe effect of smoothing one may want to prevent. +To tackle the second drawback, one can rasterize vector files, for instance by applying a regular grid +to a vector layer and assign to each pixel the value of the vector geometry most present in the pixel +(in terms of area of the intersection). +This can produce severe effect of smoothing one may want to prevent. -Other approaches also rely on comparing the distribution of some variables of interest. -For instance [@hammerbergImplicationsEmployingDetailed2018], rather than comparing the maps, -compares some model output variables using the data of the map. +Other approaches also rely on comparing the distribution of some variables of interest. +For instance [@hammerbergImplicationsEmployingDetailed2018], rather than comparing the maps, +compare some model output variables using the data of the map. -## State of the field on Local Climate Zone maps comparison. +## State of the field on Local Climate Zone maps comparison. -As Local Climate Zones emerged as a new standard for characterizing urban landscapes [@demuzereLCZGeneratorWeb2021], -specific tools are needed to allow easy automation of LCZ maps. As a matter of fact, "ground truth" is hard to -define in matters of LCZs, and one may want to compare LCZs produced by experts and by different algorithms. +As Local Climate Zones emerged as a new standard for characterizing urban landscapes [@demuzereLCZGeneratorWeb2021], +specific tools are needed to allow easy automation of LCZ maps. As a matter of fact, "ground truth" is hard to +define in matters of LCZs, and one may want to compare LCZs produced by experts and by different algorithms. The very definition of LCZs by [@stewart2012local] relies on ranges of values for several indicators, and sometimes -several LCZ types could be assigned to the corresponding geometries. Therefore, one may associate a confidence -value to the LCZ type and check if filtering pixels (for raster data) or geometries (for vector data) -accordingly to a confidence threshold has an impact on the way maps agree or disagree. +several LCZ types could be assigned to the corresponding geometries. Therefore, one may associate a confidence +value to the LCZ type and check if filtering pixels (for raster data) or geometries (for vector data) +accordingly to a confidence threshold has an impact on the way maps agree or disagree. A comparison of a raster stream result and a GIS vector stream approach was proposed by [@muhammad2022inference]. -This comparison relies on rasterising vector data. It uses several tools: QGIS, python scripts and SAGA GIS. As far as we know, -the scripts and the automation of the method are not publicly available. +This comparison relies on rasterising vector data. It uses several tools: QGIS, python scripts and SAGA GIS. +As far as we know, the scripts and the automation of the method are not publicly available. -The need for automation of vector comparison, and specific features (like standard colors or legends +The need for automation of map comparison (both raster and vector), +and specific features (like standard colors or legends for LCZs and sensitivity analaysis) justified the development of `lczexplore`. ## Features @@ -157,28 +164,28 @@ for LCZs and sensitivity analaysis) justified the development of `lczexplore`. ### General workflow and processing steps The `lczexplore` package is a set of `R` functions to import, visualize, group and compare LCZ classifications, -even when they don't use the same spatial units to classify the area. -These LCZ classifications can come from vector layers or raster layers (the latter will be vectorized -by the dedicated import function) +even when they don't use the same spatial units to classify the area. +These LCZ classifications can come from vector layers or raster layers (the latter will be vectorized +by the dedicated import function) ![Workflow and main functions of the package\label{fig:Workflow and main functions of the package}](workflow.png){width="100%"} Figure 1 describes the general workflow of the package. -Main functions are presented in plain lines, the dashed boxes and arrows represent optional steps. -These functions are presented in detail in the next section, and they allow the following steps of exploration. +Main functions are presented in plain lines, the dashed boxes and arrows represent optional steps. +These functions are presented in detail in the next section, and they allow the following steps of exploration: -1. The LCZ classifications (or any other qualitative variables) are imported -from a file (geojson or shapefile format) +1. The LCZ classifications (or any other qualitative variables) are imported + from a file (geojson or shapefile format) 2. Each LCZ classification can then be visualized 3. Some LCZ levels may be grouped in broader categories -4. A pair of LCZ classifications (or qualitative variable maps) can then be compared : +4. A pair of LCZ classifications (or qualitative variable maps) can then be compared: - a map of agreement/disagreement is produced, - - the general agreement and a pseudo-kappa indicator of agreement are computed, + - the general agreement and a pseudo-kappa indicator of agreement are computed, - the summed surface of each LCZ type is computed for each classification, - a confusion matrix shows how the levels of one LCZ classification break up into the levels of the other -5. Influence of the level of confidence on the agreement between classifications is performed -(sensitivity analysis) +5. Influence of the level of confidence on the agreement between classifications is performed + (sensitivity analysis) All the steps of the analysis can be easily automated in R, for instance on several cities at a time. @@ -190,106 +197,106 @@ The main functions are presented in this section. More details about their argum The `importLCZvect` function allows to import a LCZ classification from a geojson or a shapefile. Geometries and LCZ types are needed, but one can also optionally load unique identifiers -and a confidence level for the LCZ type of each geometry. - -The `importLCZraster` function allows the import from a raster map, and the user has to feed it a geotiff +and a confidence level for the LCZ type of each geometry. + +The `importLCZraster` function allows the import from a raster map, and the user has to feed it a geotiff and a bounding box of the area of interest. -The import functions output objects of class `simple feature`, as defined by the -openGIS consortium and as handled by the `sf` package, an R reference library for +The import functions output objects of class `simple feature`, as defined by the +openGIS consortium and as handled by the `sf` package, an R reference library for Geographical Information System Vector Data [@RJ-2018-009]. - -The `compareLCZ` function creates intersected geometries on which classifications -either totally agree or totally disagree, as seen in the figure 2, -and this prevents artificial rounding effects -that may arise with a rasterisation approach. + +The `compareLCZ` function creates intersected geometries on which classifications +either totally agree or totally disagree, as seen in the figure 2, +and this prevents artificial rounding effects +that may arise with a rasterisation approach. ![Intersecting geometries to have full agreement or disagreement \label{fig:Agreement independent of the shape of the geoms}](intersecDemo.png){width="100%"} Next, the function computes: -- the area of each LCZ type for each classification, -- the percentage of area on which the two classifications agree, and a map of this agreement, +- the area of each LCZ type for each classification, +- the percentage of area on which the two classifications agree, and a map of this agreement, - a pseudo kappa statistics which evaluates agreement beyond how two random maps may agree, - a confusion matrix of how the types of one LCZ classification break up in the types of the other, -and a graphic of this, with an indicator of the summed area for each LCZ type (useful -if the two classifications disagree on a type almost absent of the area). + and a graphic of this, with an indicator of the summed area for each LCZ type (useful + if the two classifications disagree on a type almost absent of the area). The output of these functions are shown in the minimal example section. -With the `standard` representation, comparing LCZ is made easy by a default setting of legends and colors. +With the `standard` representation, comparing LCZ maps is made easy by a default setting of legends and colors. The `alter` representation allows the user to deal with regrouped LCZ categories or any type of qualitative variables. -Levels can either be specified by the user or deduced from the data, -colors can either be defined by the user or chosen from a random palette. +Levels can either be specified by the user or deduced from the data, +colors can either be defined by the user or chosen from a random palette. -### Class levels grouping +### Class levels grouping It is sometimes useful to group some LCZ types, for instance to create a broader category for -all the urban LCZ types and another for landcape LCZ types, +all the urban LCZ types and another for landcape LCZ types, or to group the levels with similar estimated impact on an urban heat island intensity. -The `groupLCZ` function allows the user to specify the LCZ types one wants to group together, +The `groupLCZ` function allows the user to specify the LCZ types one wants to group together, the names of the new resulting categories and their corresponding colors. -One can then feed `compareLCZ` function these new groups, setting `repr="alter"`, and specify desired levels and colors. +One can then feed `compareLCZ` function these new groups, setting `repr="alter"`, and specify desired levels and colors. ![Grouping of LCZ types into larger categories \label{fig: Grouping of LCZ types into larger categories}](fromBrutToGrouped.png) ### Import and explore categorical variable (other than LCZ classifications) -The workflow of comparison of LCZ maps can be used for any pair of maps of categorical variables, -under certain limitations : -- there must not be more than 36 levels for the categorical variable to explore +The workflow of comparison of LCZ maps can be used for any pair of maps of categorical variables, +under certain limitations: +- there must not be more than 36 levels for the categorical variable to explore - the associated geometries must be (multi) polygons or easily converted to them - (typically, the package would not be suitable to compare road characterization), -- the geometries must be topographically valid (this is also true for LCZ). + (typically, the package would not be suitable to compare road characterization), +- the geometries must be topographically valid (this is also true for LCZ). The `importQualVar` function allows the import of such variables on (multi-) polygons maps. -It outputs an sf object that can be fed to the other main functions +It outputs an sf object that can be fed to the other main functions of the package (`showLCZ`, `compareLCZ`, `groupLCZ`...). ### Sensitivity analysis -The Geoclimate algorithm adds a uniqueness value to the LCZ type it assigns to a spatial unit. -It measures if another LCZ levels could have been assigned to this unit. Thus, it can be seen +The Geoclimate algorithm adds a uniqueness value to the LCZ type it assigns to a spatial unit. +It measures if another LCZ levels could have been assigned to this unit. Thus, it can be seen as a confidence value of the LCZ type. -The `lczexplore ` package allows a sensitivity analysis according to this level of confidence, -in order to answer the question : -**does keeping only geometries with a higher confidence value -make the degree of agreement between two classifications higher?** +The `lczexplore ` package allows a sensitivity analysis according to this level of confidence, +in order to answer the question: +**does keeping only geometries with a higher confidence value +make the degree of agreement between two classifications higher?** This sensitivity analysis is performed considering all LCZ types and within each individual LCZ type. ![Sensitivity analysis according to confidence for all LCZ levels \label{fig: Sensitivity analysis according to confidence}](confidSensibGen.png) -The agreement between classifications for the geometries with a confidence level higher than the threshold, +The agreement between classifications for the geometries with a confidence level higher than the threshold, and their numbers, are plotted in blue. The agreement and the numbers of geometries under the threshold are plotted in magenta. -On this example, -one can see that ditching geometries that have a confidence level lower than 0.5 leads to an increase of the agreement -up to more than 90%. The curve then tends to flatten, and the number of kept geometries decreases a lot (from 602 to 122). -One also needs to notice that on this example, most geometries didn't have a confidence value +On this example, +one can see that ditching geometries that have a confidence level lower than 0.5 increases the agreement +to more than 90%. The curve then tends to flatten, and the number of kept geometries decreases a lot (from 602 to 122). +One also needs to notice that on this example, most geometries didn't have a confidence value (7476 with a general agreement of 59.21%) # Coding implementation `lczexplore` is an R package, all its specific functions are coded in R language. -It relies on state-of-the art packages : -- geographical computation requires the **`sf`** package for vector data and the **`terra`** package for raster data, -- data management mainly requires the following packages : **`dplyr, tidyr, forcats, rlang`** -and **`methods`** packages, -- graphical production uses **`ggplot2, grDevices, cowplot`** and **`RColorBrewer`**, -- tests need the **`tinytest`** package. +It relies on state-of-the art packages: +- geographical computation requires the **`sf`** package for vector data and the **`terra`** package for raster data, +- data management mainly requires the following packages: **`dplyr, tidyr, forcats, rlang`** + and **`methods`** packages, +- graphical production uses **`ggplot2, grDevices, cowplot`** and **`RColorBrewer`**, +- tests need the **`tinytest`** package. -Every step corresponds to an R function (see the workflow on figure 1 for the name of the main functions). +Every step corresponds to an R function (see the workflow on figure 1 for the name of the main functions). -Every function has an associated file for unitary testing. +Every function has an associated file for unitary testing. # A minimal example ## Install and load -The lczexplore package can be downloaded from `https://github.com/orbisgis/lczexplore` and installed with +The lczexplore package can be downloaded from `https://github.com/orbisgis/lczexplore` and installed with the command `install_github`: ``` r @@ -298,8 +305,8 @@ devtools::install_github("orbisgis/lczexplore", build_vignettes = TRUE) library(lczexplore) ``` -In order to discover the package, vignettes can be browsed via `browseVignettes("lczexplore")` -or by calling them directly : +In order to discover the package, vignettes can be browsed via `browseVignettes("lczexplore")` +or by calling them directly: ```r vignette("lczexplore_en") @@ -310,8 +317,8 @@ vignette("lczexplore_alter") ## Import the data -This example uses two LCZ classifications of French Redon city, -produced using a single LCZ classification method (the GeoClimate workflow), +This example uses two LCZ classifications of French Redon city, +produced using a single LCZ classification method (the GeoClimate workflow), with two different input data: OpenStreetMap and the 2.2 version of the French BDTopo. @@ -340,7 +347,7 @@ redonBDT<-importLCZvect( ## Visualize the data -To visualize a LCZ classification, use the `showLCZ` function. Setting `repr` to `"standard"` directly +To visualize a LCZ classification, use the `showLCZ` function. Setting `repr` to `"standard"` directly deals with standard values of LCZ levels and colors. ```r @@ -354,24 +361,24 @@ showLCZ( ``` -The result is a map of the Local Climate Zones on the area : +The result is a map of the Local Climate Zones on the area: ![Local Climate Zones for Redon city based on the GeoClimate workflow applied to OSM data \label{fig:LCZ on Redon spatial units}](showRedonOSM.png){width="100%"} ## Compare the two LCZ classifications -To compare the two loaded LCZ classifications, use the `compareLCZ` function. +To compare the two loaded LCZ classifications, use the `compareLCZ` function. -- the `sf1` and `column1` arguments allow to specify the sf dataset of the first map, and the column in which -the LCZ levels are stored (same for `sf2` and `column2`), -- the `wf1` and `wf2` arguments take strings to specify the workflows used to produce the input data. +- the `sf1` and `column1` arguments allow to specify the sf dataset of the first map, and the column in which + the LCZ levels are stored (same for `sf2` and `column2`), +- the `wf1` and `wf2` arguments take strings to specify the workflows used to produce the input data. - The `location` argument allows to name the area of interest covered by input datasets. The 3 previous -arguments will be parsed in -the legends of the graphics (except if `title` is specified) and the name of potential csv output files, -- when `exWrite=TRUE`, the data computed to create the confusion matrix will be written -in a csv file in the working directory, + arguments will be parsed in + the legends of the graphics (except if `title` is specified) and the name of potential csv output files, +- when `exWrite=TRUE`, the data computed to create the confusion matrix will be written + in a csv file in the working directory, - if `saveG=TRUE`, the four plots created by the function will be written in a png file in the working directory. - + ```r # Compare how the BDTopo and the OpenStreetMap Data produce different classifications. # The outputs are stored in a list. @@ -388,47 +395,47 @@ All graphics are concatenated for a quick glance. The first and second maps show the spatial distribution of the first and second LCZ classifications levels, respectively. The third map shows where the two classifications agree or disagree. -The last graphic is a confusion matrix: how the LCZ types of the first classification break-up in those -of the second, in percentage of the surface. +The last graphic is a confusion matrix: how the LCZ types of the first classification break-up in those +of the second, in percentage of the surface. `CompareLCZ ` outputs a list called `matConfOut` which contains: -- `$data`, intersected geometries, their identifiers and associated confidence value -(if fed to the fonction), their LCZ type and their area, -- `$areas`, the summed area for each LCZ for both classifications, -- `$matConfLarge`, the confusion matrix, +- `$data`, intersected geometries, their identifiers and associated confidence value + (if fed to the fonction), their LCZ type and their area, +- `$areas`, the summed area for each LCZ for both classifications, +- `$matConfLarge`, the confusion matrix, - `$percAgg`, the general agreement of the two classification on the whole area -(as a percentage of the global surface of the area), -- `$pseudoK`, the value of a heuristic pseudo Cohen's Kappa coefficient of agreement. - -The value `pseudoK` corresponds to a Kappa, -where the cells of the cross tabulation would be -weighted by the percentage of the concerned surface. - -One can see in a quick glance, that the BDTopo workflow leads to more and smaller Spatial Reference Units (1553 RSU) -than the OpenStreetMap workflow (521 RSU). The third map shows that while the classifications tend to -agree on wide vegetation areas, there seem to be more some discrepancies in the urban areas. -The last graphics helps to refine this analysis: one can notice that -both workflows quite agree for "compact mid" and "low plants" LCZ levels (89% and 88 % of the concerned areas). -On the contrary, only 48% of the areas set to "dense trees" by BDTopo workflow are also set to + (as a percentage of the global surface of the area), +- `$pseudoK`, the value of a heuristic pseudo Cohen's Kappa coefficient of agreement. + +The value `pseudoK` corresponds to a Kappa, +where the cells of the cross tabulation would be +weighted by the percentage of the concerned surface. + +One can see in a quick glance, that the BDTopo workflow leads to more and smaller Spatial Reference Units (1553 RSU) +than the OpenStreetMap workflow (521 RSU). The third map shows that while the classifications tend to +agree on wide vegetation areas, there seem to be more some discrepancies in the urban areas. +The last graphics helps to refine this analysis: one can notice that +both workflows quite agree for "compact mid" and "low plants" LCZ levels (89% and 88 % of the concerned areas). +On the contrary, only 48% of the areas set to "dense trees" by BDTopo workflow are also set to "dense trees" by OpenStreetMap workflow, while 37% of these areas are set as "low plants." -In the same way, 73% of the areas set to "compact low" by +In the same way, 73% of the areas set to "compact low" by BDTopo workflow are set to "compact mid" by OpenStreetMap workflow. This is coherent with the fact that building heights are often missing on OpenStreetMap and that the algorithm that GeoClimate uses to predict them is less precise than -the available information of BDTopo. One may read more in [@bernardGenericAlgorithmAutomatically2023] - about differences between these workflows. +the available information of BDTopo. One may read more in [@bernardGenericAlgorithmAutomatically2023] +about differences between these workflows. ## Study the impact of confidence on agreement The `confidSensib` function makes a sensitivity analysis of the agreement according to the threshold of confidence above which one keeps the geometries of the compared maps. -To perform this analysis, the confidence value and the identifier of each geometry must be fed to the comparison -function. The `$data` slot is then passed to `confidSensib`. -The `saveG` allows to set the path to a folder where resulting graphics will be saved. +To perform this analysis, the confidence value and the identifier of each geometry must be fed to the comparison +function. The `$data` slot is then passed to `confidSensib`. +The `saveG` allows to set the path to a folder where resulting graphics will be saved. -The values of confidence for which the agreement will be computed are determined by the range of +The values of confidence for which the agreement will be computed are determined by the range of confidence values present in the data and by the number of points, set by the `nPoints` argument. @@ -461,28 +468,28 @@ sensitAnalysis<-confidSensib(inputDf=comparison$data, filePath="", Figure 7 shows the resulting graphics for the agreement per LCZ type (types not present in the dataset are excluded). -![Sensitivity analysis according to confidence by LCZ levels ](confidSensibByLCZ.png) +![Sensitivity analysis according to confidence by LCZ levels ](confidSensibByLCZ.png) For each LCZ type, the x-axis shows the minimum confidence threshold. The y-axis shows the agreement levels. -Each cyan point shows the average agreement between classifications for spatial units where -the minimum confidence value is greater than the x-axis value. +Each cyan point shows the average agreement between classifications for spatial units where +the minimum confidence value is greater than the x-axis value. -As one wants to be sure the dropped units +As one wants to be sure the dropped units didn't have a greater agreement, they are showed as magenta triangles. -For this particular example, it seems that for the "Open Low" LCZ type, +For this particular example, it seems that for the "Open Low" LCZ type, the greater the confidence, the smaller the agreement! -This unexpected result is explained by the fact that in our case, the confidence qualifies the method, not the data. +This unexpected result is explained by the fact that in our case, the confidence qualifies the method, not the data. In this example, in the OSM dataset which is compared, -the building height are mostly estimated using a statistical method [@bernardEstimationMissingBuilding2022] as stated above. +the building height are mostly estimated using a statistical method [@bernardEstimationMissingBuilding2022] as stated above. ## Group some levels and perform the same analysis -The `groupLCZ` function aggregates chosen levels into broader categories. For each category, a vector is needed, -which name is the name of the broader category to create and which values -are the levels to be grouped in this new category. +The `groupLCZ` function aggregates chosen levels into broader categories. For each category, a vector is needed, +which name is the name of the broader category to create and which values +are the levels to be grouped in this new category. ```r redonOSMgrouped<-groupLCZ(redonOSM,column="LCZ_PRIMARY", @@ -505,11 +512,11 @@ redonBDTgrouped<-groupLCZ(redonBDT,column="LCZ_PRIMARY", ``` -By default, the column where the new categories are stored is named `"grouped"`, +By default, the column where the new categories are stored is named `"grouped"`, but it can be set with the argument `outCol`. It is the possible to perform the same analysis as on standard LCZ classifications, -as shown in the following example : +as shown in the following example: ```r showLCZ(redonOSMgrouped, column="grouped",repr="alter", @@ -525,16 +532,16 @@ compareLCZ(sf1=redonOSMgrouped, column1="grouped", wf1="OpenStreetMap data", ![Map of grouped levels on the city of Redon \label{fig: Grouped LCZ on the city of Redon}](redonGrouped.png) -You can also map any qualitative variable using this grouped representation, +You can also map any qualitative variable using this grouped representation, as long as you specify the expected levels the same way. ## An example of qualitative variables -The function `importQualVar` allows you to import maps of qualitative variables on (multi)polygons. -For instance, classifications of urban tissue called +The function `importQualVar` allows you to import maps of qualitative variables on (multi)polygons. +For instance, classifications of urban tissue called Urban Typolgy by Random Forest [@bocherGeoprocessingFrameworkCompute2018] are available as examples in this package. -After the import, the usual functions can be used, as shown in the following code : +After the import, the usual functions can be used, as shown in the following code: ```r utrfRedonBDT<-importQualVar(dirPath=paste0( @@ -544,11 +551,11 @@ utrfRedonBDT<-importQualVar(dirPath=paste0( showLCZ(sf=utrfRedonBDT, column="TYPO_MAJ",repr="alter", title = " UTRF classification of the French city of Redon") ``` -![An example of some qualitative variable : Urban Typology by Random Forest (UTRF)](importQualVarUTRF.png) +![An example of some qualitative variable: Urban Typology by Random Forest (UTRF)](importQualVarUTRF.png) -Figure 9 represents the UTRF classification of the French city of Redon, +Figure 9 represents the UTRF classification of the French city of Redon, as computed by the GeoClimate workflow on BDTopo v2.2 data. The colors were not specified and therefoer were -randomly picked from a palette. +randomly picked from a palette. ```r utrfRedonOSM<- @@ -577,7 +584,7 @@ Guidelines. # Research projects involving lczexplore -The lczexplore package was developed thanks to the project PÆNDORA2 -(Pour la gestion du confort estival : Données, Outils et Recherche-Action) (2022 -2025), funded by ADEME. +The lczexplore package was developed thanks to the project PÆNDORA2 +(Pour la gestion du confort estival: Données, Outils et Recherche-Action) (2022 -2025), funded by ADEME. -# References +# References \ No newline at end of file diff --git a/man/importLCZraster.Rd b/man/importLCZraster.Rd index d089dcf..abd3c35 100644 --- a/man/importLCZraster.Rd +++ b/man/importLCZraster.Rd @@ -45,7 +45,7 @@ A future version may include the world data once a strategy is defined to deal w } \examples{ redonBbox<-importLCZvect(dirPath=paste0(system.file("extdata", package = "lczexplore"), -"/bdtopo_2_2/Redon"), file="rsu_lcz.geojson",column="LCZ_PRIMARY", output="bBox") +"/bdtopo_2_2/Redon"), file="rsu_lcz.geojson", column="LCZ_PRIMARY", output="bBox") redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), fileName="redonWudapt.tif",bBox=redonBbox) @@ -62,5 +62,5 @@ fileName="redonWudapt.tif",bBox=redonBbox) #fileName="CONUS_LCZ_map_NLCD_v1.0_epsg4326.tif", #column="CONUS_LCZ_map_NLCD_v1.0_epsg4326" # ,bBox=sanDiegoBbox) -#showLCZ(sanDiegoWudapt,column="CONUS_LCZ_map_NLCD_v1.0_epsg4326") +#showLCZ(sanDiegoWudapt, column="CONUS_LCZ_map_NLCD_v1.0_epsg4326") } diff --git a/vignettes/lczexplore_alter.Rmd b/vignettes/lczexplore_alter.Rmd index 1dff9eb..1bfd1f9 100644 --- a/vignettes/lczexplore_alter.Rmd +++ b/vignettes/lczexplore_alter.Rmd @@ -31,7 +31,7 @@ The purpose of this package is to easily compare different local climate zone (L on the same study territory. For these LCZ, the `repr="standard"` representation sets proper levels and colors by default. You can read the `lczexplore_english` vignette for an overview. -This vignette deals with other cases, when `repr="alter"`, that is : +This vignette deals with other cases, when `repr="alter"`, that is: - when one groups LCZ levels into broader categories, - when LCZ levels are expressed in an unexpected format, - or even compares maps of other qualitative variables. diff --git a/vignettes/lczexplore_en.Rmd b/vignettes/lczexplore_en.Rmd index a0d16a6..7b27130 100644 --- a/vignettes/lczexplore_en.Rmd +++ b/vignettes/lczexplore_en.Rmd @@ -24,7 +24,7 @@ if (!require("png")) { ``` -# A package to explore Local Climate Zones : lczexplore +# A package to explore Local Climate Zones: lczexplore ## Purpose and origin The lczexplore package was developed thanks to the PAENDORA2 (Pour la gestion du confort estival : Données, Outils et Recherche-Action, 2022 -2025, funded by ADEME, a French agency for ecological transition). @@ -42,18 +42,18 @@ It has been extended to compare any pair of qualitative variable set on valid ge ## Installation -The following allows the installation from the github repository : (`devtools::install_github("orbisgis/lczexplore", build_vignettes = TRUE)`). +The following allows the installation from the github repository: (`devtools::install_github("orbisgis/lczexplore", build_vignettes = TRUE)`). On can also install from the tar.gz file and install it (see `?install.packages`). -Load the package : `library(lczexplore)`. +Load the package: `library(lczexplore)`. ```{r} library(lczexplore) ``` -# First use-case : load a file with geometries and standard LCZ +# First use-case: load a file with geometries and standard LCZ ## Import files with importLCZvect function @@ -111,7 +111,7 @@ showLCZ(sf=redonOSM,wf="OSM",column="LCZ_PRIMARY",repr="standard",drop=TRUE) ``` ### Alternative visualization -The non-standard representation, triggered with `repr=alter` is useful when : +The non-standard representation, triggered with `repr=alter` is useful when: - one wants to **regroup** some LCZ types into more general categories, - the LCZ **don't have a standard encoding** - one want's to use **custom colors** @@ -121,7 +121,7 @@ With `repr=alter`, one passes the vector of possible levels to the argument `LCZ If no vector of levels or no vector of colors is given, the levels will be deduced from the unique values present in the data, and the colors will be picked from the "Polychrome 36" palette of the `grDevices` package. -For instance : one can first plot the column without knowing the LCZ levels present. +For instance: one can first plot the column without knowing the LCZ levels present. ```{r, fig.dim = c(8, 6)} # Choice of random colors from a palette testCol <- palette.colors(n=17, palette="Polychrome 36") @@ -166,10 +166,10 @@ showLCZ(redonOSMgrouped, column="grouped",repr="alter",wf="OSM", # Compare two LCZ classification with the function compareLCZ **The purpose of this package is to easily compare local climate zone classifications produced by different algorithms on the same study area.** -In our example, the GeoClimate workflow was used with two different input data to produce two LCZ classifications : +In our example, the GeoClimate workflow was used with two different input data to produce two LCZ classifications: the BD TOPO® v2.2, produced by the French National Institute of Geographic and Forest Information, and OpenStreetMap. -NOTE : The vignette "lczexplore_raster_vector" explores in detail another example with WUDAPT raster data. +NOTE: The vignette "lczexplore_raster_vector" explores in detail another example with WUDAPT raster data. One has to call `compareLCZ` and feed it, for each dataset, @@ -180,12 +180,12 @@ you need to tell which dataset is the reference - A map of each LCZ classification is plotted. - The function then intersects the geometries of both sf objects in order to get geometries where the **two classification either totally agree either totally disagree.** This agreement is plotted on a third graphics. -- At last, a confusion matrix (or agreement matrix) is computed : +- At last, a confusion matrix (or agreement matrix) is computed: the area of each intersected geometry and the values of the two LCZ classifications are used to show how one type of the first classification breaks up into the levels of the second classification. - The matrix is shown in the fourth and last graphics. -NOTE : if the two data sets to compare have the same column names, +NOTE: if the two data sets to compare have the same column names, the compareLCZ function will concatenate a ".1" string to the column names of the second file *The graphical output includes 4 graphs and is easier to read after zooming or exporting.* @@ -239,7 +239,7 @@ comparisonGrouped<-compareLCZ(sf1=redonBDT,column1="LCZ_PRIMARY", wf1="groupedBD ## Output data for further analysis -`CompareLCZ `outputs a list called `matConfOut` which contains : +`CompareLCZ `outputs a list called `matConfOut` which contains: - `$data` the intersected geometries, their identifiers (if `geomID` was not empty), their LCZ types and their areas, - `$matConfLarge` the confusion matrix, @@ -247,7 +247,7 @@ comparisonGrouped<-compareLCZ(sf1=redonBDT,column1="LCZ_PRIMARY", wf1="groupedBD - `$areas` the summed area for each LCZ of both classifications. -At last : it `exWrite=TRUE` the data are exported to a .csv file whose name +At last: it `exWrite=TRUE` the data are exported to a .csv file whose name is created from the argument `wf1` and `wf2`. It can then be loaded for further analysis. ```{r} @@ -266,7 +266,7 @@ GeoClimate supplies a **uniqueness value**, between 0 and 1. The closer it is to LCZ type was a good candidate. So this uniqueness can be seen as a confidence value. -## Import the necessary data : LCZ type, but also confidence. +## Import the necessary data: LCZ type, but also confidence. When using the `importLCZvect` function one needs to specify the confidence value associated to the LCZ (`confid` argument). On can also set the name of the geometry identifier (`geomID` argument ). @@ -288,11 +288,11 @@ redonCompare<-compareLCZ(sf1=redonBDT,wf1="bdt", geomID1 = "ID_RSU",column1 ="LC The function `confidSensib` performs the sensitivity analysis from the output of `compareLCZ`. -NOTE : if the two data sets to compare have the same column names, +NOTE: if the two data sets to compare have the same column names, the compareLCZ function will concatenate a ".1" string to the column names of the second file, so the enriched names will be the ones to feed `confidSensib`. -The question we want to answer is : **Does the agreement between the two classification gets bigger if we keep only the geometries for which the LCZ value is associated to a confidence value bigger than a thershold?** +The question we want to answer is: **Does the agreement between the two classification gets bigger if we keep only the geometries for which the LCZ value is associated to a confidence value bigger than a thershold?** The span of the confidence values is divided on as many points as the user chooses with the argument `nPoints` diff --git a/vignettes/lczexplore_raster_vector.Rmd b/vignettes/lczexplore_raster_vector.Rmd index 68c4cca..29c8495 100644 --- a/vignettes/lczexplore_raster_vector.Rmd +++ b/vignettes/lczexplore_raster_vector.Rmd @@ -23,23 +23,23 @@ if (!require("png")) { ``` -To install and discover the package, please read the lczexplore_english vignette. To load it simply type : +To install and discover the package, please read the lczexplore_english vignette. To load it simply type: ```{r} library(lczexplore) ``` -Usecase : comparing the LCZ available on the WUDAPT european LCZ map and the Geoclimate approach using OpenStreetMap input data +Usecase: comparing the LCZ available on the WUDAPT european LCZ map and the Geoclimate approach using OpenStreetMap input data This vignette illustrates the use of the package to compare maps produced with different approaches, it does not aim at drawing conclusion on the relevance of these methods, nor does it aim at describing them in details. # Import and visualize a raster map of LCZ -## Data : the Redon territory from the european LCZ map produced by the WUDAPT project +## Data: the Redon territory from the european LCZ map produced by the WUDAPT project The World Urban Database and Access Portal Tools is a project which aims at creating LCZ with earth observation data. -The details of the project and the related papers can be found on the website of the project : https://www.wudapt.org/ +The details of the project and the related papers can be found on the website of the project: https://www.wudapt.org/ -The map we are going to use in this vignette is the European LCZ map, as described in the paper available at the following url : +The map we are going to use in this vignette is the European LCZ map, as described in the paper available at the following url: https://doi.org/10.1371/journal.pone.0214474 As this method is one of the most used we included the map tif in the embedded data of the package. @@ -56,7 +56,7 @@ redonBbox<-importLCZvect(dirPath=paste0(system.file("extdata", package = "lczexp ``` The second step is to import the raster map and use the previous bounding box to crop the territory of interest. -The importLCZraster function performs this in a simple call : +The importLCZraster function performs this in a simple call: ```{r} redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), fileName="redonWudapt.tif",bBox=redonBbox) @@ -77,7 +77,7 @@ One can then use standard R functions to explore the data. summary(redonWudapt) summary(redonWudapt$EU_LCZ_map) ``` -One can see, for instance that no pixel of the imported territory set to one of the following levels : 1, 2, 4, 5, 7, 10, 103 or 105, +One can see, for instance that no pixel of the imported territory set to one of the following levels: 1, 2, 4, 5, 7, 10, 103 or 105, or that the most present LCZ type is 104, with 1116 pixels. @@ -98,7 +98,7 @@ The following code shows an example of color choice. # Import and visualize a vector layer map of LCZ -## Data : LCZ on the Redon territory produced by the GeoClimate workflow using OpenStreetMap as input. +## Data: LCZ on the Redon territory produced by the GeoClimate workflow using OpenStreetMap as input. These data are embedded in `lczexplore`. On can import them using the `importLCZvect` function. This function allows to load geojson or shp files, and one must specify the name of the column containing the LCZ types. From 2c90e707af8460f5197623068c233e11cd5680e4 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Thu, 19 Oct 2023 12:03:02 +0200 Subject: [PATCH 14/18] ShinyApp saves config file in tmp if no folder is specified, but outputs the message in console and not through --- R/importLCZraster.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/importLCZraster.R b/R/importLCZraster.R index 0bb3bf2..2058ef6 100644 --- a/R/importLCZraster.R +++ b/R/importLCZraster.R @@ -6,7 +6,7 @@ #' #' @param dirPath is the path to the directory where the #' @param fileName is by default \'EU_LCZ_map.tif\' but can be changed for test prurposes. Will be useful when other zones will be added -#' @param column indicates the name of the column containing LCZ values, all other +#' @param column indicates the name of the column which will contain the LCZ read from the raster file (tif or geo tif) #' @param typeLevels indicates a named vector of the unique values contained in column, #' @param zone set to europe by default, may include world once a strategy is defined #' @param bBox bBox is the bounding box needed to crop the wudapt tiff file. From 7ab763e1102ff659e601d7bd0a4d76cddbaacef7 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Thu, 19 Oct 2023 14:28:36 +0200 Subject: [PATCH 15/18] With Vignettes rebuilt --- NAMESPACE | 4 - R/geoClimateCall.R | 44 ----------- R/geoClimateConfigFile.R | 144 ------------------------------------ R/importLCZraster.R | 8 +- man/geoClimateCall.Rd | 36 --------- man/geoClimateConfigFile.Rd | 80 -------------------- man/importLCZraster.Rd | 12 ++- man/showLCZ.Rd | 2 +- 8 files changed, 17 insertions(+), 313 deletions(-) delete mode 100644 R/geoClimateCall.R delete mode 100644 R/geoClimateConfigFile.R delete mode 100644 man/geoClimateCall.Rd delete mode 100644 man/geoClimateConfigFile.Rd diff --git a/NAMESPACE b/NAMESPACE index 34073d4..ba26ad4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,8 +5,6 @@ export(areColors) export(compareLCZ) export(confidSensib) export(fetchLCZ) -export(geoClimateCall) -export(geoClimateConfigFile) export(groupLCZ) export(importLCZgc) export(importLCZraster) @@ -37,8 +35,6 @@ importFrom(ggplot2,geom_sf) importFrom(ggplot2,ggtitle) importFrom(ggplot2,guides) importFrom(grDevices,palette.colors) -importFrom(jsonlite,toJSON) -importFrom(jsonlite,unbox) importFrom(magrittr,"%>%") importFrom(stats,quantile) importFrom(terra,as.polygons) diff --git a/R/geoClimateCall.R b/R/geoClimateCall.R deleted file mode 100644 index 1a3df33..0000000 --- a/R/geoClimateCall.R +++ /dev/null @@ -1,44 +0,0 @@ -#' Calls GeoClimate and feeds it a configuration file by building a command an using system (only tested on linux) -#' @param jarFilePath tells where the geoclimate jar file is, default points to the embedded jar file, -#' i.e. the latest snapshot version when the package was built. -#' Versions can be downloaded from https://github.com/orbisgis/geoclimate/wiki/Download -#' @param configFilePath points to the configuration JSON file for GeoClimate, typically a file created with the -#' geoClimateConfigFile function -#' @param wf is the workflow to use with GeoClimate, the default is OSM for OpenStreetMap. -#' The other possible value is "BDTOPO_V2". Other values will be added (e.g. for BDTOPO_V3) when tested. -#' @return returns nothing but files will be created by GeoClimate in the folder specified in the -#' JSON configuration file. -#' @export -#' @examples -#' test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", -#' rsuIndics = c("LCZ","TEB","UTRF"), -#' gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", -#' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) -#' geoClimateCall( -#' jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", -#' configFilePath="/tmp/Redonosm.json",w="osm") -#' test -geoClimateCall<-function(jarFilePath,configFilePath,wf="OSM") { - command<-paste0( - "java -jar ", jarFilePath, " -f ", configFilePath, " -w ", wf) - print(command) - system(command) - -} - -# test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Allaire", -# rsuIndics = c("LCZ","TEB","UTRF"), -# gridIndics = c("BUILDING_FRACTION", -# "BUILDING_HEIGHT", -# "WATER_FRACTION", -# "VEGETATION_FRACTION", -# "ROAD_FRACTION", -# "IMPERVIOUS_FRACTION", -# "LCZ_PRIMARY", -# "LCZ_FRACTION", -# "UTRF")) -# -# geoClimateCall( -# jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", -# configFilePath="/tmp/Redonosm.json",w="osm") -# test \ No newline at end of file diff --git a/R/geoClimateConfigFile.R b/R/geoClimateConfigFile.R deleted file mode 100644 index 9807341..0000000 --- a/R/geoClimateConfigFile.R +++ /dev/null @@ -1,144 +0,0 @@ -#' Builds a JSON configuration file for GeoClimate workflow -#' @param locations is either the town or the coordinates of the bounding box of the area on which GeoClimate will run. -#' If a town name, it will be fed to the Nominoe API, through the overpass API of OpenStreetMap. -#' @param wf is the workflow used by GeoClimate. For now, only osm is available, for OpenStreetMap, but bdt for -#' BD TOPO of IGN should be added when an online database is available. -#' @param outFolder indicates where the results of GeoClimate will be put -#' @param rsuIndics is a vector with the indicators one wants to compute at the RSU scale. The default is c("LCZ","TEB","UTRF"), -#' @param svfSimplified uses the simplified method to calculate skyview factor, default = TRUE -#' @param estimatedHeight uses an algorithm to esitmate the missing building height, default = TRUE -#' @param grid_x_size is the x size for the grid if some grid indicators are to be computed, default=100 -#' @param grid_y_size is the x size for the grid if some grid indicators are to be computed, default=100 -#' @param rowCol if grid_x_size and grid_y_size are not set, one cal set the number of rows and cols throug rowCol, -#' but the recommended and defualt is FALSE -#' @param outputType is the format of GeoClimate outputs, default="geojson", -#' @param gridIndics is a vector containing the indicators to compute at the grid scale. Default is -#' c("BUILDING_FRACTION", -#' "BUILDING_HEIGHT", -#' "WATER_FRACTION", -#' "VEGETATION_FRACTION", -#' "ROAD_FRACTION", -#' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF") -#' @param outConfigDir is the folder were the resulting JSON file will be put, the folder where GeoClimate will read it from -#' (different from out outFolder, where GeoClimates will put its geoJSON ouputs), default is "/tmp" -#' @param outConfigFile is the name of your configuration file, if anb empty string, a name woill be created from location -#' and workflow parameters. -#' @param forceSRID some BD TOPO input file may not have an srid, this forces srid to be 2154 -#' @importFrom jsonlite unbox toJSON -#' @return returns a JSON configuration file to be fed to GeoClimate -#' @export -#' @examples -#' test<-geoClimateConfigFile(outConfigFile="", wf="osm",outFolder="/tmp",locations="Redon", -#' rsuIndics = c("LCZ","TEB","UTRF"), -#' gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", -#' "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) -#' test -geoClimateConfigFile<-function(wf,locations,forceSRID=FALSE, - outFolder="/tmp", - rsuIndics=c("LCZ","TEB","UTRF"), - svfSimplified = TRUE, - estimatedHeight = TRUE, - grid_x_size = 100, - grid_y_size = 100, - rowCol = FALSE, - outputType = "geojson", - gridIndics = c("BUILDING_FRACTION", - "BUILDING_HEIGHT", - "WATER_FRACTION", - "VEGETATION_FRACTION", - "ROAD_FRACTION", - "IMPERVIOUS_FRACTION", - "LCZ_PRIMARY", - "LCZ_FRACTION", - "UTRF"), - outConfigDir = "/tmp", - outConfigFile = "configFile", - BDTinFolder = "",BDTinseeCode=29301, - writeNow = FALSE) { - # description<-"Test de description unique" - - if (wf=="OSM"){description<-"Processing OSM data"} else { - if (wf=="BDTOPO_V2.2") {description<-"Processing BDTopo v2 data"} else { - if (wf=="BDTOPO_V3") { - description<-"Processing BDTopo v3 data"} - else { description<-paste0("Processing on an unrecognized workflow: ", wf) - } - } - } - -outFolder<-tryCatch( # This hideous tryCatch deals with weird shinyDirChoose behavior - { - list(folder=unbox(outFolder))}, - error=function(e){ - list(folder="\tmp") - } -) - - -if (wf == "OSM"){ - input<-list(locations=locations) - } else { if (grep("BDT",wf)==1) { - if (forceSRID==FALSE){ - input<- - list( - folder= tryCatch( - unbox(BDTinFolder), - error=function(e){ - list(folder="\tmp") - }), - locations=BDTinseeCode - ) - } else { if (forceSRID==TRUE) { - input<- - list( - folder= tryCatch( - unbox(BDTinFolder), - error=function(e){ - list(folder="\tmp") - }) - , - locations=BDTinseeCode, - srid=unbox(2154)) - }} - }} - - - - parameters<-list( - rsu_indicators = list( - indicatorUse = rsuIndics, - svSimplified = unbox(svfSimplified), - estimatedHeight = unbox(estimatedHeight)), - grid_indicators = list( - x_size = unbox(grid_x_size), y_size = unbox(grid_y_size), - rowCol = unbox(rowCol), - output = unbox(outputType), - indicators = gridIndics - ) -) - - -listJSON <- list(description=unbox(description), input=input,output=outFolder,parameters=parameters) - -output<-toJSON(x=listJSON, - pretty=TRUE) - - - -if (outConfigFile=="") { outConfigFile<-paste0(locations,wf) } - -if (writeNow == TRUE){ - write(output,file=paste0(outConfigDir,"/",outConfigFile,".json")) -} - -return(output) - -} -# -# library(jsonlite) -# test<-geoClimateConfigFile(outConfigFile="", wf="BDTOPO_V2.2",outFolder=list(folder="/tmp",srid=2154),locations="Allaire", -# rsuIndics = c("LCZ","TEB","UTRF"), -# gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", -# "IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) -# test - diff --git a/R/importLCZraster.R b/R/importLCZraster.R index 2058ef6..7b1e6a8 100644 --- a/R/importLCZraster.R +++ b/R/importLCZraster.R @@ -5,8 +5,9 @@ #' A future version may include the world data once a strategy is defined to deal with CRS. #' #' @param dirPath is the path to the directory where the -#' @param fileName is by default \'EU_LCZ_map.tif\' but can be changed for test prurposes. Will be useful when other zones will be added -#' @param column indicates the name of the column which will contain the LCZ read from the raster file (tif or geo tif) +#' @param fileName is the name of the raster file (tif or geotif), by default \'EU_LCZ_map.tif\' . +#' Will be useful when other zones will be added +#' @param column indicates the name of the column which will contain the LCZ in the output file #' @param typeLevels indicates a named vector of the unique values contained in column, #' @param zone set to europe by default, may include world once a strategy is defined #' @param bBox bBox is the bounding box needed to crop the wudapt tiff file. @@ -32,7 +33,8 @@ #' # redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), #' # fileName="redonWudapt.tif",bBox=redonBbox) #' -#' # another way to get the bounding box when one doesn't want to compare to a vector map is to enter it's coordinates +#' # another way to get the bounding box when one doesn't want +#' #to compare to a vector map is to enter it's coordinates #' # and feed them to st_bbox() of the sf package. #' #' # the following example can only be executed when user has downloaded diff --git a/man/geoClimateCall.Rd b/man/geoClimateCall.Rd deleted file mode 100644 index 3c3b0e0..0000000 --- a/man/geoClimateCall.Rd +++ /dev/null @@ -1,36 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/geoClimateCall.R -\name{geoClimateCall} -\alias{geoClimateCall} -\title{Calls GeoClimate and feeds it a configuration file by building a command an using system (only tested on linux)} -\usage{ -geoClimateCall(jarFilePath, configFilePath, wf = "OSM") -} -\arguments{ -\item{jarFilePath}{tells where the geoclimate jar file is, default points to the embedded jar file, -i.e. the latest snapshot version when the package was built. -Versions can be downloaded from https://github.com/orbisgis/geoclimate/wiki/Download} - -\item{configFilePath}{points to the configuration JSON file for GeoClimate, typically a file created with the -geoClimateConfigFile function} - -\item{wf}{is the workflow to use with GeoClimate, the default is OSM for OpenStreetMap. -The other possible value is "BDTOPO_V2". Other values will be added (e.g. for BDTOPO_V3) when tested.} -} -\value{ -returns nothing but files will be created by GeoClimate in the folder specified in the -JSON configuration file. -} -\description{ -Calls GeoClimate and feeds it a configuration file by building a command an using system (only tested on linux) -} -\examples{ -test<-geoClimateConfigFile(outFile="", wf="osm",outFolder="/tmp",locations="Redon", -rsuIndics = c("LCZ","TEB","UTRF"), -gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", -"IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) -geoClimateCall( -jarFilePath= "/home/gousseff/Documents/2_CodesSources/GeoClimate/GeoClimateDefaultCaseV2/geoclimate-0.0.2-SNAPSHOT.jar", -configFilePath="/tmp/Redonosm.json",w="osm") -test -} diff --git a/man/geoClimateConfigFile.Rd b/man/geoClimateConfigFile.Rd deleted file mode 100644 index cc8dbb7..0000000 --- a/man/geoClimateConfigFile.Rd +++ /dev/null @@ -1,80 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/geoClimateConfigFile.R -\name{geoClimateConfigFile} -\alias{geoClimateConfigFile} -\title{Builds a JSON configuration file for GeoClimate workflow} -\usage{ -geoClimateConfigFile( - wf, - locations, - forceSRID = FALSE, - outFolder = "/tmp", - rsuIndics = c("LCZ", "TEB", "UTRF"), - svSimplified = TRUE, - estimatedHeight = TRUE, - grid_x_size = 100, - grid_y_size = 100, - rowCol = FALSE, - outputType = "geojson", - gridIndics = c("BUILDING_FRACTION", "BUILDING_HEIGHT", "WATER_FRACTION", - "VEGETATION_FRACTION", "ROAD_FRACTION", "IMPERVIOUS_FRACTION", "LCZ_PRIMARY", - "LCZ_FRACTION", "UTRF"), - outConfigDir = "/tmp", - outConfigFile = "", - BDTinFolder = "", - BDTinseeCode = 29301 -) -} -\arguments{ -\item{wf}{is the workflow used by GeoClimate. For now, only osm is available, for OpenStreetMap, but bdt for -BD TOPO of IGN should be added when an online database is available.} - -\item{locations}{is either the town or the coordinates of the bounding box of the area on which GeoClimate will run. -If a town name, it will be fed to the Nominoe API, through the overpass API of OpenStreetMap.} - -\item{forceSRID}{some BD TOPO input file may not have an srid, this forces srid to be 2154} - -\item{outFolder}{indicates where the results of GeoClimate will be put} - -\item{rsuIndics}{is a vector with the indicators one wants to compute at the RSU scale. The default is c("LCZ","TEB","UTRF"),} - -\item{svSimplified}{uses the simplified method to calculate skyview factor, default = TRUE} - -\item{estimatedHeight}{uses an algorithm to esitmate the missing building height, default = TRUE} - -\item{grid_x_size}{is the x size for the grid if some grid indicators are to be computed, default=100} - -\item{grid_y_size}{is the x size for the grid if some grid indicators are to be computed, default=100} - -\item{rowCol}{if grid_x_size and grid_y_size are not set, one cal set the number of rows and cols throug rowCol, -but the recommended and defualt is FALSE} - -\item{outputType}{is the format of GeoClimate outputs, default="geojson",} - -\item{gridIndics}{is a vector containing the indicators to compute at the grid scale. Default is -c("BUILDING_FRACTION", -"BUILDING_HEIGHT", -"WATER_FRACTION", -"VEGETATION_FRACTION", -"ROAD_FRACTION", -"IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")} - -\item{outConfigDir}{is the folder were the resulting JSON file will be put, the folder where GeoClimate will read it from -(different from out outFolder, where GeoClimates will put its geoJSON ouputs), default is "/tmp"} - -\item{outConfigFile}{is the name of your configuration file, if anb empty string, a name woill be created from location -and workflow parameters.} -} -\value{ -returns a JSON configuration file to be fed to GeoClimate -} -\description{ -Builds a JSON configuration file for GeoClimate workflow -} -\examples{ -test<-geoClimateConfigFile(outConfigFile="", wf="osm",outFolder="/tmp",locations="Redon", -rsuIndics = c("LCZ","TEB","UTRF"), -gridIndics = c("BUILDING_FRACTION","BUILDING_HEIGHT","WATER_FRACTION","VEGETATION_FRACTION","ROAD_FRACTION", -"IMPERVIOUS_FRACTION","LCZ_PRIMARY","LCZ_FRACTION","UTRF")) -test -} diff --git a/man/importLCZraster.Rd b/man/importLCZraster.Rd index abd3c35..78227da 100644 --- a/man/importLCZraster.Rd +++ b/man/importLCZraster.Rd @@ -29,7 +29,7 @@ It can be produced bu the importLCZvect function. It can either be of class bBox \item{fileName}{is by default \'EU_LCZ_map.tif\' but can be changed for test prurposes. Will be useful when other zones will be added} -\item{column}{indicates the name of the column containing LCZ values, all other} +\item{column}{indicates the name of the column which will contain the LCZ read from the raster file (tif or geo tif)} \item{typeLevels}{indicates a named vector of the unique values contained in column,} } @@ -50,6 +50,16 @@ redonBbox<-importLCZvect(dirPath=paste0(system.file("extdata", package = "lczexp redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), fileName="redonWudapt.tif",bBox=redonBbox) +# another way to get the bounding box when one explores a given city would be the use of the +# getbb() function from the osmdata package. +# This exaample requires the osmdata package and therefore is not executed here +# redonBbox<-osmdata::getbb("Redon") +# redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), +# fileName="redonWudapt.tif",bBox=redonBbox) + +# another way to get the bounding box when one doesn't want to compare to a vector map is to enter it's coordinates +# and feed them to st_bbox() of the sf package. + # the following example can only be executed when user has downloaded # CONUS-wide LCZ map and Training Areas on WUDAPT website # sanDiegobBoxCoord<-st_sf(a=1:2, geom=st_sfc( diff --git a/man/showLCZ.Rd b/man/showLCZ.Rd index 70c80dd..2a39594 100644 --- a/man/showLCZ.Rd +++ b/man/showLCZ.Rd @@ -41,7 +41,7 @@ in your dataset and colors associated to these levels when not in the standard r For more details about this, read the "lcz_explore_alter" vignette.} } \value{ -no object is returned, but plots of the LCZ levels are produced +return the plot of the LCZ levels } \description{ Produces a simple representation of the LCZ contained in an sf file. From 6fa52b228daddf465526df1d38e925a16c2d8fd2 Mon Sep 17 00:00:00 2001 From: MGousseff Date: Wed, 18 Oct 2023 17:40:44 +0200 Subject: [PATCH 16/18] With Vignettes rebuilt and example in importLCZraster on 2 lines --- man/importLCZraster.Rd | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/man/importLCZraster.Rd b/man/importLCZraster.Rd index 78227da..b5c896d 100644 --- a/man/importLCZraster.Rd +++ b/man/importLCZraster.Rd @@ -27,9 +27,10 @@ importLCZraster( \item{bBox}{bBox is the bounding box needed to crop the wudapt tiff file. It can be produced bu the importLCZvect function. It can either be of class bBox or of class sfc} -\item{fileName}{is by default \'EU_LCZ_map.tif\' but can be changed for test prurposes. Will be useful when other zones will be added} +\item{fileName}{is the name of the raster file (tif or geotif), by default \'EU_LCZ_map.tif\' . +Will be useful when other zones will be added} -\item{column}{indicates the name of the column which will contain the LCZ read from the raster file (tif or geo tif)} +\item{column}{indicates the name of the column which will contain the LCZ in the output file} \item{typeLevels}{indicates a named vector of the unique values contained in column,} } @@ -57,7 +58,8 @@ fileName="redonWudapt.tif",bBox=redonBbox) # redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), # fileName="redonWudapt.tif",bBox=redonBbox) -# another way to get the bounding box when one doesn't want to compare to a vector map is to enter it's coordinates +# another way to get the bounding box when one doesn't want +#to compare to a vector map is to enter it's coordinates # and feed them to st_bbox() of the sf package. # the following example can only be executed when user has downloaded From ffb52a4bedb5c9b1295fa928d5ca55bd02b161a6 Mon Sep 17 00:00:00 2001 From: Matthieu Gousseff Date: Thu, 19 Oct 2023 15:47:30 +0200 Subject: [PATCH 17/18] Update importLCZraster.R typo --- R/importLCZraster.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/importLCZraster.R b/R/importLCZraster.R index 7b1e6a8..8593fc7 100644 --- a/R/importLCZraster.R +++ b/R/importLCZraster.R @@ -28,7 +28,7 @@ #' #' # another way to get the bounding box when one explores a given city would be the use of the #' # getbb() function from the osmdata package. -#' # This exaample requires the osmdata package and therefore is not executed here +#' # This example requires the osmdata package and therefore is not executed here #' # redonBbox<-osmdata::getbb("Redon") #' # redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), #' # fileName="redonWudapt.tif",bBox=redonBbox) @@ -117,4 +117,4 @@ importLCZraster<-function(dirPath,zone="europe",bBox,fileName="EU_LCZ_map.tif", -} \ No newline at end of file +} From f63ab86cd8b60bd740a3b0365f07fd13fe55aaae Mon Sep 17 00:00:00 2001 From: Matthieu Gousseff Date: Thu, 19 Oct 2023 15:50:34 +0200 Subject: [PATCH 18/18] Update importLCZraster.R Fixed typos in the example of importLCZraster --- R/importLCZraster.R | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/R/importLCZraster.R b/R/importLCZraster.R index 8593fc7..7d944c1 100644 --- a/R/importLCZraster.R +++ b/R/importLCZraster.R @@ -10,9 +10,10 @@ #' @param column indicates the name of the column which will contain the LCZ in the output file #' @param typeLevels indicates a named vector of the unique values contained in column, #' @param zone set to europe by default, may include world once a strategy is defined -#' @param bBox bBox is the bounding box needed to crop the wudapt tiff file. -#' It can be produced bu the importLCZvect function. It can either be of class bBox or of class sfc -#' @return an sf file containing the geom and LCZ levels from the WUDAPT Europe tiff within the bBox bounding box +#' @param bBox bBox is the bounding box needed to crop the raster tiff file. +#' It can be produced by the importLCZvect function if one has a vect map o the same zone, +#' it can be a set of coordinates. It can either be of class bBox or of class sfc. +#' @return an sf file containing the geom and LCZ levels from the raster within the bBox bounding box #' @import sf dplyr forcats #' @importFrom terra crop #' @importFrom terra rast @@ -26,7 +27,7 @@ #' redonWudapt<-importLCZraster(system.file("extdata", package = "lczexplore"), #' fileName="redonWudapt.tif",bBox=redonBbox) #' -#' # another way to get the bounding box when one explores a given city would be the use of the +#' # Another way to get the bounding box when one explores a given city would be the use of the #' # getbb() function from the osmdata package. #' # This example requires the osmdata package and therefore is not executed here #' # redonBbox<-osmdata::getbb("Redon") @@ -34,14 +35,14 @@ #' # fileName="redonWudapt.tif",bBox=redonBbox) #' #' # another way to get the bounding box when one doesn't want -#' #to compare to a vector map is to enter it's coordinates +#' # to compare to a vector map is to enter it's coordinates #' # and feed them to st_bbox() of the sf package. #' #' # the following example can only be executed when user has downloaded #' # CONUS-wide LCZ map and Training Areas on WUDAPT website #' # sanDiegobBoxCoord<-st_sf(a=1:2, geom=st_sfc( -#' #st_point(c(-117.175198,32.707289)), -#' #st_point(c(-117.112198,32.750900)),crs = 4326 +#' # st_point(c(-117.175198,32.707289)), +#' # st_point(c(-117.112198,32.750900)),crs = 4326 #' #)) #' #sanDiegoBbox<-st_bbox(sanDiegobBoxCoord) #' #sanDiegoWudapt<-importLCZraster(