[GRASS-dev] small changes to r.walk
Colin Nielsen
colin.nielsen at gmail.com
Thu Nov 13 15:06:31 EST 2008
If I understand your comment correctly then the current r.walk
functionality is actually doing what you want it to be doing (ie.
there is no problem). r.walk does not create a full cumulative cost
map and then add the friction map, rather it combines the cumulative
cost and friction cost with each origin pixel to neighbouring pixel
calculation. If this was unclear in the help file perhaps an update to
clarify is needed.
See the snippet of code below from r.walk/main.c where "case 1"
represents the consideration of the western neighbour:
1024 switch (neighbor) {
1025 case 1:
1026 dtm_value = &W_dtm;
1027 segment_get(&dtm_in_seg, dtm_value, row, col);
1028 cost_value = &W_cost;
1029 segment_get(&cost_in_seg, cost_value, row, col);
1030 if (G_is_d_null_value(cost_value))
1031 continue;
1032 if (((W_dtm - my_dtm) / EW_fac) >= 0)
1033 fcost_dtm = (double)((double)(W_dtm - my_dtm) * b);
1034 else if (((W_dtm - my_dtm) / EW_fac) < (slope_factor))
1035 fcost_dtm = (double)((double)(W_dtm - my_dtm) * d);
1036 else
1037 fcost_dtm = (double)((double)(W_dtm - my_dtm) * c);
1038 fcost_cost = ((double)(W_cost + my_cost) / 2.0);
1039 min_cost =
1040 pres_cell->min_cost + fcost_dtm + (EW_fac * a) +
1041 lambda * fcost_cost * EW_fac;
1042 break;
The last calculation shows that the neighbour's new cost (min_cost)
will be equal to the origin's cumulative cost (pres_cell->min_cost) +
the topographic/slope cost to move to the western neighbour
(fcost_dtm) + lambda * the friction cost to move to the western
neighbour (fcost_cost).
I hope that helps and that I wasn't more long winded than was called for :).
-Colin
On Thu, Nov 13, 2008 at 2:34 PM, Michael Barton <michael.barton at asu.edu> wrote:
> Hi Colin,
>
>
> On Nov 13, 2008, at 11:38 AM, Colin Nielsen wrote:
>
>> Not that I'm disagreeing with the need to change this functionality,
>> but based on the way the algorithm incorporates the friction map, you
>> can currently put zero for lambda and any map for the friction to have
>> it work on slope alone. This is a little easier than the method you
>> mentioned.
>
> This is a handy workaround. However, it is probably better in the long run
> to fix this than to depend on a workaround.
>
>
>>
>>
>> ie. total cost = movement time cost + (0 * friction)
>>
>> Further, I believe to make lambda and friction optional will take
>> relatively substantial re-writes.
>
> Hopefully, this won't really take that much effort. However, while we're on
> the subject, one of my students noticed something that might take more
> substantial rewrites and I guess I should mention it now.
>
> If we are correct on how r.cost uses a friction map (and this is not 100%
> certain), there is a fundamental flaw. A cost distance map should have cells
> that represent cumulative cost outward from a starting point. r.walk
> automatically calculates this in seconds, making it a really useful module
> to have in GRASS.
>
> If the friction map is added in AFTER the initial cumulative walking time
> cost map is generated, the result will violate the cumulative nature of the
> cost map. Imagine a map generated by r.walk with a cumulative time cost
> along a line of cells as follows:
>
> 0 | 100 | 120 | 150 | 250 | 350 |
>
> Now ADD a friction map to this
>
> 0 | 0 | 200 | 300 | 0 | -150 |
>
> Here is the result
>
> 0 | 100 | 320 | 450 | 250 | 200 |
>
> The final map is no longer the cumulative time to travel from the origin.
> More distant cells take less time to reach than closer cells.
>
> The friction map needs to be incorporated into the cost along with
> topographic slope when the initial time map is created, not afterwards.
>
> Michael
>
>
>>
>>
>> -Colin
>>
>> On Thu, Nov 13, 2008 at 1:16 PM, Michael Barton <michael.barton at asu.edu>
>> wrote:
>>>
>>> Several weeks back, Helena gave a very good explanation of how r.walk
>>> actually works. It makes very good sense (see below). However, from this
>>> explanation, it is clear that lambda and a friction map should be
>>> *optional*
>>> rather than *required* as they are now.
>>> The main part of r.walk calculates the time (in seconds) needed to walk
>>> across a landscape.
>>> For any cell,
>>> total time = (walking time in seconds to traverse the cell given its
>>> slope)
>>> + (lambda * friction map)
>>> Lambda is a weighting coefficient to convert the friction map to units
>>> that
>>> match the costs due to slope (i.e., units in seconds normally).
>>> If you want to calculate walking time to traverse a landscape that is
>>> based
>>> solely on the topography (i.e., slope), then you need a friction map with
>>> a
>>> value of 0; lambda can be anything.
>>> So this should be optional. Currently, you need to create a 0 friction
>>> map
>>> and try to figure out what lambda should be in order to run r.walk. This
>>> is
>>> sort of pointless and can cause considerable confusion.
>>> So, can lambda and friction map be changed to optional arguments for our
>>> upcoming releases?
>>> Thanks
>>> Michael
>>> ____________
>>> Begin forwarded message:
>>>
>>> From: Michael Barton <michael.barton at asu.edu>
>>> Date: October 10, 2008 9:27:46 PM GMT-07:00
>>> To: Helena Mitasova <hmitaso at unity.ncsu.edu>
>>> Cc: grass developers <grass-dev at lists.osgeo.org>, Ullah Isaac
>>> <Isaac.Ullah at asu.edu>, David.Quixal at uv.es, Sean Bergin
>>> <Sean.Bergin at asu.edu>, Moreno Martín Andrea <andrea.moreno at uv.es>
>>> Subject: Re: [GRASS-dev] default for r.walk
>>> Thanks very much for this thorough explanation Helena. It is quite
>>> helpful.
>>> I hope that Roberto can verify (or correct) this.
>>>
>>> I'm copying some folks who have been working with r.walk recently. Our
>>> lab
>>> discussions on this caused me to raise these questions.
>>>
>>> On the issue I first asked about, it seems that lambda should either 1)
>>> have
>>> a default value of 1 or 2) be optional.
>>>
>>> Michael
>>>
>>>
>>> On Oct 10, 2008, at 6:09 PM, Helena Mitasova wrote:
>>>
>>>
>>> On Oct 10, 2008, at 7:39 PM, Michael Barton wrote:
>>>
>>>
>>>
>>>
>>> On Oct 10, 2008, at 11:32 AM, Helena Mitasova wrote:
>>>
>>> I opened the code and it has it right in header:
>>>
>>> TOTAL COST = [(WALKING ENERGY ) + (LAMBDA*FRICTION)]
>>>
>>> maybe this is how it should go into the man page
>>>
>>> That seems like a good idea.
>>>
>>> This suggests that friction and lambda should be in some kind of energy
>>> units.
>>>
>>> However, as I understand it, the values in an r.walk map--using the
>>> default
>>> values--are an estimate of the number of seconds to traverse a cell
>>> walking
>>> 'normally' (i.e., according to the default values). Is this true anyone?
>>> If
>>> so, wouldn't the additive friction need to be in time units?
>>>
>>> I'm not trying to be dense, but trying to get clear about what the output
>>> is
>>> actually telling us, since it does not seem to be in arbitrary units like
>>> r.cost is (unless you do some numerical massaging).
>>>
>>> these are perfectly valid questions - authors should probably answer them
>>> rather than me
>>>
>>> but we tried to put some explanation based on the manual in to the
>>> appendix
>>> of GRASSbook
>>>
>>> and I have just covered it in the class so I had to spend some time
>>> trying
>>> to understand it.
>>>
>>> the units are - according to the manual - time - see below
>>>
>>> S, H are meters but the coefficients a,b,c,d are 1/speed which is
>>> sec/meter
>>> giving you time in seconds,
>>>
>>> then friction map can be either in units of time (sec) and lambda is
>>> unitless weight
>>>
>>> or friction is unitless factor and lambda is in seconds which converts it
>>> to
>>> time.
>>>
>>> So the results are in seconds - when you derive contours from the results
>>> you will get isochrones -
>>>
>>> so you can delineate an area where the person gets within 2 hours or
>>> whatever time you chose.
>>>
>>> But it would be really good to hear from the authors because these are my
>>> interpretations
>>>
>>> of the manual and my experiments with the module. The man page is pretty
>>> good it just needs to be more clear that the cost is measured by time (if
>>> I
>>> understand it correctly)
>>>
>>> Helena
>>>
>>>
>>> T= [(a)*(Delta S)] + [(b)*(Delta H uphill)] + [(c)*(Delta H moderate
>>> downhill)] + [(d)*(Delta H steep downhill)]
>>>
>>> where:
>>>
>>> T is time of movement in seconds,
>>>
>>> Delta S is the distance covered in meters,
>>>
>>> Delta H is the altitude difference in meter.
>>>
>>> The a, b, c, d parameters take in account movement speed in the different
>>> conditions and are linked to:
>>>
>>> * a: underfoot condition (a=1/walking_speed)
>>>
>>> * b: underfoot condition and cost associated to movement uphill
>>>
>>> * c: underfoot condition and cost associated to movement moderate
>>> downhill
>>>
>>> * d: underfoot condition and cost associated to movement steep downhill
>>>
>>> It has been proved that moving downhill is favourable up to a specific
>>> slope
>>> value threshold, after that it becomes unfavourable. The default slope
>>> value
>>> threshold (slope factor) is -0.2125, corresponding to tan(-12),
>>> calibrated
>>> on human behaviour (>5 and <12 degrees: moderate downhill; >12 degrees:
>>> steep downhill). The default values for a, b, c, d are those proposed by
>>> Langmuir (0.72, 6.0, 1.9998, -1.9998), based on man walking effort in
>>> standard conditions.
>>>
>>> The lambda parameter of the linear equation combining movement and
>>> friction
>>> costs:
>>>
>>> total cost = movement time cost + (lambda) * friction costs
>>>
>>> must be set in the option section of r.walk.
>>>
>>>
>>>
>>>
>>> Michael
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Oct 10, 2008, at 2:21 PM, Michael Barton wrote:
>>>
>>> I've been emailing with Helena to try to understand exactly how lambda
>>> and a
>>> friction surface interacts with information about topography (extracted
>>> from
>>> a DEM) in r.walk. It seems a good idea to put this back on the list.
>>> Perhaps
>>> I'm the only one a little in the dark, but maybe it can help others.
>>>
>>> On Oct 10, 2008, at 10:40 AM, Helena Mitasova wrote:
>>>
>>>
>>> To clarify for me, is it
>>>
>>> total cost = (movement time cost + lambda) * friction costs
>>>
>>> OR
>>>
>>> total cost = movement time cost + (lambda * friction costs)
>>>
>>> I did not look into the code but if there are no brackets in the code,
>>> this
>>> second interpretation applies.
>>>
>>> For anyone familiar with the code, is this the case? If so, should I be
>>> thinking in time units for creating a friction map? If I remember, r.walk
>>> normally outputs in seconds to traverse the cell.
>>>
>>> So, should the friction map be in additional seconds to traverse the
>>> cell?
>>> Or is friction a weighting factor (i.e., multiplicative rather than
>>> additive)?
>>>
>>> Thanks
>>>
>>> Michael
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> grass-dev mailing list
>>> grass-dev at lists.osgeo.org
>>> http://lists.osgeo.org/mailman/listinfo/grass-dev
>>>
>
>
More information about the grass-dev
mailing list