Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blue_line_key_to_watershed() can error when too close to mouth #16

Open
joethorley opened this issue Nov 6, 2020 · 17 comments
Open

blue_line_key_to_watershed() can error when too close to mouth #16

joethorley opened this issue Nov 6, 2020 · 17 comments

Comments

@joethorley
Copy link
Member

joethorley commented Nov 6, 2020

> fwatlasbc:::fwa_blue_line_key_to_watershed(356528119)
Error: API request failed [404]: Unable to read data from: fwa_watershedatmeasure
.
Backtrace:
    █
 1. └─fwatlasbc:::fwa_blue_line_key_to_watershed(356528119)
 2.   └─fwapgr::fwa_watershed_at_measure(...) /Users/joe/Code/fwatlasbc/R/watershed.R:29:2
 3.     └─fwapgr:::fwa_function(...) /Users/joe/Code/fwapgr/R/functions.R:117:2
 4.       └─fwapgr:::fwa_api(path, query) /Users/joe/Code/fwapgr/R/functions.R:38:2
 5.         └─fwapgr:::chk_response_status(resp) /Users/joe/Code/fwapgr/R/utils.R:20:2
 6.           └─chk::abort_chk(glue("API request failed [{status_code(x)}]: {msg}")) /Users/joe/Code/fwapgr/R/chk.R:6:2
 7.             └─chk::err(..., n = n, tidy = tidy, .subclass = "chk_error")
 8.               └─rlang::exec(abort, msg, .subclass = .subclass, !!!args[named])
> fwatlasbc:::fwa_blue_line_key_to_watershed(356528119, distance_from_mouth = 50)
Simple feature collection with 1 feature and 2 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 1797649 ymin: 590132.3 xmax: 1808033 ymax: 604684.9
projected CRS:  NAD83 / BC Albers
  blue_line_key distance_from_mouth                       geometry
1     356528119                  50 POLYGON ((1797738 599112.5,...

Presumably because too flat to work out watershed. Could deal with with more informative error message ie suggestion to increase distance from mouth.

@sebdalgarno
Copy link
Member

I think this issue in fwapg is looking at this: smnorris/fwapg#7

@sebdalgarno
Copy link
Member

I dont think we can glean any more information from the error itself that would specifically point to this issue, but we could add a general rule that if downstream_route_measure = 0 and API error, then make suggestion to move it a few meters

@joethorley
Copy link
Member Author

That seems like a good option

@joethorley
Copy link
Member Author

This suggestion actually turns out to be annoying and I now think we should just go back to the raw error.

@joethorley
Copy link
Member Author

Also for consistency across the interface.

@joethorley
Copy link
Member Author

maybe I'm over reacting to this - I'll think on it

@smnorris
Copy link
Collaborator

smnorris commented Nov 12, 2020

I have noticed that measures of 0 are more likely to fail but didn't bother looking into it. Just because requesting a watershed measure 0 does not actually require all the fancy logic that watershed_at_measure provides - for my tools I can just ask the db for the source watershed polygons upstream of that location. Definitely worth debugging, it is probably just a precision issue somewhere.

I think fwapg # 7 is more of a specific case, but it may well be related.

@smnorris
Copy link
Collaborator

Actually, smnorris/fwapg#7 is unrelated. That one is likely more of a pain to resolve.

@smnorris
Copy link
Collaborator

Also, regarding this:

because too flat to work out watershed

fwapg doesn't use the DEM anywhere - you'll get funny results in some flat areas but that is mostly based on the FWA polygons your point of interest falls in.

I need to put together a document/presentation on how watershed_at_measure works

@joethorley joethorley reopened this Nov 12, 2020
@joethorley
Copy link
Member Author

@smnorris - it would be great to resolve because watershed area for a given point is so useful for modelling fish densities

@joethorley
Copy link
Member Author

@smnorris - have you had a change to document how watershed_at_measure works - is it based off of the stream network segments?

@smnorris
Copy link
Collaborator

smnorris commented Dec 4, 2020

No, not yet. Probably not till January, I'm swamped.
Basically what it does is select and aggregate all the fundamental watershed polygons upstream of the fundamental watershed in which the point lies.
Depending on where the point is, one of several things will happen
a. If the point is less than 50m instream from the bottom of the fundamental watershed in which the point lies, aggregate that fundamental watershed with watersheds upstream (noted as KEEP in result's property refine_method)
b. If the point is less than 100m instream from the top of the fundamental watershed in which the point lies, don't include that watershed polygon in the output (refine_method = DROP)
c. if the point is between these two measures, we return refine_method = DEM - if you want a better definition of the watershed within the first order watershed in which the point lies, you'll have to refine that with the DEM. See bcbasins for how I do this but for most watersheds it is not an issue - only on 1st or 2nd order streams will this make much difference
d. Finally, if the point is on a polygonal river/canal, refine_method = CUT and we cut the watershed polygons at the location of the point, cutting the fundamental watersheds across the banks of the river. This is the biggest value added in the function and the only instance where spatial data / linework returned from the function is altered from the source FWA linework.

Hope this helps - take a look at whse_basemapping.fwa_watersheds_poly and compare features in there to outputs you get when requesting a watershed at a point on a river polygon. Because most of the hydrometric stations have been processed successfully I think many of the edge case problems have been eliminated but there will still be problems where there is an island in the river, and perhaps elsewhere too. smnorris/fwapg#5 (comment)

@joethorley
Copy link
Member Author

Thanks @smnorris - this is really helpful!

@joethorley
Copy link
Member Author

Hi @smnorris - I've put together the following documentation for the R function.

Can you confirm the order of the if else statements (or does placement on a polygon river/canal) override 1 and 2?

And can you provide a little more detail on what happens to the fundamental watershed in number 4?

#' 1. If the point is < 50 m upstream from the bottom of the fundamental
#' watershed then it is included in the aggregation (recorded as KEEP in the
#' refine_method property).
#'
#' 2. Else if the point is < 100m downstream from the top of the fundamental
#' watershed then it is not included in the aggregation (recorded as DROP in the
#' refine_method property).
#'
#' 3. Else if the point is on a polygonal river/canal the fundamental watershed is
#' cut across the banks of the river before being included in the aggregation
#' (recorded as CUT in the refine_method property).
#'
#' 4. Otherwise something else happens (recorded as DEM in the refine_method
#' property).

@smnorris
Copy link
Collaborator

smnorris commented Sep 7, 2021

That order is not quite right - but I had to refer to the postgres manual to check, it isn't very clear in the script. The first statement that returns true in the CASE WHEN block is evaluated, then the rest are ignored. So:

#' 1. If the point is on a polygonal river/canal the fundamental watershed is
#' cut across the banks of the river before being included in the aggregation
#' (recorded as CUT in the refine_method property).
#'
#' 2. Else if the point is < 100m downstream from the top of the fundamental
#' watershed then it is not included in the aggregation (recorded as DROP in the
#' refine_method property).
#'
#' 3. Else if the point is < 50 m upstream from the bottom of the fundamental
#' watershed then it is included in the aggregation (recorded as KEEP in the
#' refine_method property).
#'
#' 4. Otherwise something else happens (recorded as DEM in the refine_method
#' property).

@smnorris
Copy link
Collaborator

smnorris commented Sep 8, 2021

For 4, postprocessing of the fundamental watershed intersecting the point was required for the job that the script was built for. When just using FWA_WatershedAtMeasure nothing else will happen, behaviour will be the same as 2 / DROP - everything upstream of the given fundamental watershed will be aggregated and returned.

@smnorris
Copy link
Collaborator

smnorris commented Sep 8, 2021

There is also one initial check, if the point is in a lake, return watershed of everything draining into that lake.
This will produce unexpected results if you're working with points that are near large reservoirs. For example, in the Peace, be sure to match to the correct stream to avoid selecting everything upstream of Hudson's Hope.

#' 1. If the point is within a lake, return everything upstream of the lake's outflow
#'
#' 2. If the point is on a polygonal river/canal the fundamental watershed is
#' cut across the banks of the river before being included in the aggregation
#' (recorded as CUT in the refine_method property).
#'
#' 3. Else if the point is < 100m downstream from the top of the fundamental
#' watershed then it is not included in the aggregation (recorded as DROP in the
#' refine_method property).
#'
#' 4. Else if the point is < 50 m upstream from the bottom of the fundamental
#' watershed then it is included in the aggregation (recorded as KEEP in the
#' refine_method property).
#'
#' 5. Otherwise something else happens (recorded as DEM in the refine_method
#' property).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants