22# '
33# ' Creates the flow networkd table used by RHESSys
44# ' @param flownet_name The name of the flow network file to be created. Will be coerced to have ".flow" extension if not already present.
5- # ' @param readin readin indicates the maps to be used. If CreateFlowmet.R is run it's own, this should point to the template which references the maps(or values)
6- # ' used for the various levels and statevars. Otherwise, if run inside of RHESSysPreprocess, readin will use the map data from world_gen.R,
7- # ' Streams map, and other optional maps, still need to be specified.
8- # ' @param asp_rules List of aspatial structure and inputs. Also can be path to rules file - must be used along with template input.
5+ # ' @param asprules List of aspatial structure and inputs. Also can be path to rules file - must be used along with template input.
96# ' @param road_width >0, defaults to 1.
107# ' @inheritParams RHESSysPreprocess
118# ' @author Will Burke
129# ' @export
1310
1411CreateFlownet = function (flownet_name ,
15- readin = NULL ,
12+ template = NULL ,
1613 type = " raster" ,
1714 typepars = NULL ,
18- asp_rules = NULL ,
15+ asprules = NULL ,
1916 streams = NULL ,
2017 overwrite = FALSE ,
2118 roads = NULL ,
@@ -39,15 +36,11 @@ CreateFlownet = function(flownet_name,
3936 if (! is.logical(overwrite )) {stop(" overwrite must be logical" )} # check overwrite inputs
4037 if (file.exists(flownet_name ) & overwrite == FALSE ) {stop(noquote(paste(" Flowtable" ,flownet_name ," already exists." )))}
4138
42- if (! wrapper & is.character(readin )) { # if run outside of rhessyspreprocess.R, and if readin is character. readin is the template (and path)
43- template_list = template_read(readin )
44- template_clean = template_list [[1 ]] # template in list form
45- var_names = template_list [[2 ]] # names of template vars
46- map_info = template_list [[5 ]] # tables of maps and their inputs/names in the template
47- cfmaps = rbind(map_info ,c(" cell_length" ," none" ), c(" streams" ," none" ), c(" roads" ," none" ), c(" impervious" ," none" ),c(" roofs" ," none" ))
48- } else if (wrapper | (! wrapper & is.matrix(readin ))) { # map info is passsed directly from world gen - either in wrapper or outside of wrapper and readin is matrix
49- cfmaps = readin
50- }
39+ template_list = template_read(template )
40+ template_clean = template_list [[1 ]] # template in list form
41+ var_names = template_list [[2 ]] # names of template vars
42+ map_info = template_list [[5 ]] # tables of maps and their inputs/names in the template
43+ cfmaps = rbind(map_info ,c(" cell_length" ," none" ), c(" streams" ," none" ), c(" roads" ," none" ), c(" impervious" ," none" ),c(" roofs" ," none" ))
5144
5245 # Check for streams map, menu allows input of stream map
5346 if (is.null(streams ) & (cfmaps [cfmaps [,1 ] == " streams" ,2 ] == " none" | is.na(cfmaps [cfmaps [,1 ] == " streams" ,2 ]))) {
@@ -80,7 +73,7 @@ CreateFlownet = function(flownet_name,
8073 }
8174
8275 # check inputs are maps or values
83- notamap = cfmaps [suppressWarnings( which(! is.na(as.numeric(cfmaps [,2 ])))),1 ]
76+ notamap = cfmaps [suppressWarnings(which(! is.na(as.numeric(cfmaps [,2 ])))),1 ]
8477 maps_in = unique(cfmaps [cfmaps [,2 ] != " none" & ! cfmaps [,1 ] %in% notamap ,2 ])
8578
8679 # ------------------------------ Use GIS_read to get maps ------------------------------
@@ -116,22 +109,29 @@ CreateFlownet = function(flownet_name,
116109 raw_impervious_data = NULL
117110 if (! is.null(impervious )) {raw_impervious_data = map_list [[cfmaps [cfmaps [,1 ] == " impervious" ,2 ]]]}
118111
112+ # TODO - this should get cleaned up eventually - there's at least 2 different versions of the maps being used
113+ if (length(readmap @ data [,1 ]) == 1 ) {
114+ map_df = as.data.frame(readmap @ data ) # works for 1 patch world
115+ } else {
116+ map_df = as.data.frame(readmap ) # make data frame for ease of use
117+ }
118+
119119 # read aspatial rules if needed
120- if (! is.null(asp_rules ) && is.character( asp_rules )) {
120+ if (! is.null(asprules )) {
121121 asp_map = template_clean [[which(var_names == " asp_rule" )]][3 ] # get rule map/value
122- if (suppressWarnings(any(is.na(as.numeric(asp_map ))))) { # if it's a map
122+ patch_map = map_df [[cfmaps [cfmaps [,1 ] == " patch" ,2 ]]] # set for use later - overwrite if using mode
123+
124+ if (suppressWarnings(is.na(as.numeric(asp_map )))) { # if it's a map
123125 asp_map = gsub(" .tif|.tiff" ," " ,asp_map )
124126 asp_mapdata = as.data.frame(readmap )[asp_map ]
125127
126128 # --- doing manipulation of the asp map if needed here ---
127- if (template_clean [[which(var_names == " asp_rule" )]][2 ] == " mode" ) {
128-
129+ if (template_clean [[which(var_names == " asp_rule" )]][2 ] == " mode" ) {
129130 # mode for aggregating by mode
130131 mode_fun = function (x ) {
131132 ux <- unique(x )
132133 ux [which.max(tabulate(match(x , ux )))]
133134 }
134-
135135 # fun to check if rules are all unique per patch (kinda slow but oh well) -----
136136 check_rules = function (patches , asp_rules ) {
137137 patches_u = unique(patches [! is.na(patches )])
@@ -155,28 +155,25 @@ CreateFlownet = function(flownet_name,
155155 map_info [map_info [, 1 ] == " strata" , 2 ]))
156156 level_names = unique(gsub(" .tiff|.tif|.asc" ," " ,level_names ))
157157
158- if (length(readmap @ data [,1 ]) == 1 ) {
159- map_df = as.data.frame(readmap @ data ) # works for 1 patch world
160- } else {
161- map_df = as.data.frame(readmap ) # make data frame for ease of use
162- }
163-
164- asp_maps = aggregate(map_df $ asprule , by = map_df [level_names ], FUN = mode_fun , simplify = T )
158+ asp_maps = aggregate(map_df [[cfmaps [cfmaps [,1 ] == " asp_rule" ,2 ]]], by = map_df [level_names ], FUN = mode_fun , simplify = T )
165159 names(asp_maps )[which(names(asp_maps ) == " x" )] = " asprule"
166160
167- rules_out = check_rules(patches = asp_maps $ pch_30m1000 , asp_rules = asp_maps $ asprule )
161+ patch_map = asp_maps [[cfmaps [cfmaps [,1 ] == " patch" ,2 ]]]
162+
163+ rules_out = check_rules(patches = patch_map , asp_rules = asp_maps $ asprule )
164+
168165 if (! is.null(rules_out )) {
169166 print(rules_out )
170167 stop(" Mode of rules was attempted but there are still patches with multiple rules. Check input maps." )
171168 }
172-
173169 asp_mapdata = asp_maps $ asprule
174170 }
175171
176- } else if (suppressWarnings(all(! is.na(as.numeric(asp_map ))))) { # if is a single number
177- asp_mapdata = as.numeric(asp_map )
172+ } else { # if is a single number
173+ asp_mapdata = map_df [[cfmaps [cfmaps [,1 ] == " basin" ,2 ]]]
174+ asp_mapdata [! is.na(asp_mapdata )] = as.numeric(asp_map )
178175 }
179- asp_list = aspatial_patches(asprules = asp_rules , asp_mapdata = asp_mapdata )
176+ asp_list = aspatial_patches(asprules = asprules , asp_mapdata = asp_mapdata )
180177 }
181178
182179 # ------------------------------ Make flownet list ------------------------------
@@ -197,15 +194,8 @@ CreateFlownet = function(flownet_name,
197194 skip_hillslope_check = skip_hillslope_check )
198195
199196 # ------------------------------ Multiscale routing/aspatial patches ------------------------------
200- if (! is.null(asp_rules )) {
201- if (" asp_rule" %in% notamap ) {
202- map_list [[" asp_rule" ]] = raw_basin_data
203- map_list [[" asp_rule" ]][! is.na(map_list [[" asp_rule" ]])] = as.numeric(cfmaps [cfmaps [,1 ] == " asp_rule" ,2 ])
204- # cfmaps = rbind(cfmaps, c("asp_rule", "asp_rule"))
205- cfmaps [cfmaps [,1 ] == " asp_rule" , 2 ] = " asp_rule"
206- }
207-
208- CF1 = multiscale_flow(CF1 = CF1 , asp_maps = asp_maps , cfmaps = cfmaps , asp_list = asp_list )
197+ if (! is.null(asprules )) {
198+ CF1 = multiscale_flow(CF1 = CF1 , asp_map = asp_mapdata , patch_map = patch_map , asp_list = asp_list )
209199 }
210200
211201 # ---------- Flownet list to flow table file ----------
0 commit comments