# How to use GRASS v.kernel to calculate point densities along a network?

In a road network, I need to select the segments where a minimum of 5 dots occur (1 dot = 1 address) over a distance of 100 m (the image attached illustrates my question). I'm trying to use GRASS v.kernel for this, with a uniform distribution but I do not know how to configure it. Using these parameters:

v.kernel -v input=MY_LOCATIONS net=MY_NETWORK output=MY_OUTPUT stddeviation=100 distmax=1 mult=200 node=split kernel=uniform

I do get segments as a result with values going up where more dots occur, but I do not know hot to interpret them.

In the image attached: segments such as indicated by the green circle are what I am looking for. • A kernel calculation ignores the topology and metric (distances) along the street network. It therefore cannot address this question. It could be used to screen a better answer, in the sense that wherever the local kernel density is too small, you won't find five points within 100m of each other either on or off the network. But where the kernel density is large, it might be picking up points on a totally different street segment. Aug 4, 2015 at 14:38
• @whuber Are you sure about your comment? I'm using GRASS v.kernel with a network, not a raster. I consulted the article that the GRASS implementation is based on ([here](www.csis.u-tokyo.ac.jp/dp/89.pdf)). It seems to be all about point densities on a network. By the way, I'm fine with picking up points on topologically connected segments.
– JTh
Aug 4, 2015 at 17:01
• Thank you for bringing that to my attention! I had (incorrectly) assumed that because you were using GRASS, then you were performing purely raster-based calculations. If indeed that paper's algorithm is implemented in GRASS--and it seems to be--then it's the perfect solution to your problem. How to interpret the output is a matter to be referred to the documentation, which offers different normalization options: see the `-n` and `-m` flags. Aug 4, 2015 at 17:29

I may have found a solution to my own question, but I am not sure:

v.kernel -v input=MY_LOCATIONS net=MY_NETWORK output=MY_OUTPUT stddeviation=57.735 distmax=1 mult=200 kernel=uniform

The parameters and values in bold are important. Where do they come from? The kernel surrounding each dot has the uniform distribution with a range of 100 m at both sides of the dot location. Hence, the 'range' (b - a) of the uniform distribution is 200 m. The standard deviation of a uniform distribution 1 / (b - a) is (b - a) / sqrt(12), hence the standard deviation parameter is 200 / sqrt(12) = 57.735 (reference)

Because the height of the uniform distribution is 1/200, I multiply the result with 200 (hence parameter mult=200).

Eventually, I get line segments having values indicating the number of dots over a length of 100 m.

The result seems to be correct, but I am not sure.

Edit:

Well, I'm not so sure that my use of the module is correct after all. Overall, the kernel density estimate increases on segments where more dots occurs, as it should be. But there are some contradictory results that I cannot explain. Below is a screenshot, showing the network (thin dashed line), the locations on the network (red dots) and the kernel density estimate result having a value of 5 or more (thick purple lines). I don't understand the result for the two regions indicated in orange. Less than 3 dots over a span of 100 m should never have a kernel of more than 3 (yet, it is 5 in my result). Also, a segment with about 8 dots over just over 100 m should have a kernel density estimate of at least 5, but it is less in my output (hence, no thick purple line). Can anybody explain this? Am I using the GRASS module correctly?

Thanks. Edit (2018-01-20):

The module v.kernel has changed in GRASS 7.2.2. Here is an update of how I would use the module now:

``````SET XMIN=227511
SET XMAX=240244
SET YMIN=202932
SET YMAX=213221

g.region res=1 n=%YMAX% s=%YMIN% e=%XMAX% w=%XMIN%
v.in.ogr dsn=./network.shp output=V_NETWORK --overwrite --quiet
v.in.ogr dsn=./events.shp output=V_EVENTS --overwrite --quiet

SET input=V_EVENTS
SET net=V_NETWORK
SET net_output=V_KERNEL_OUTPUT
SET dsize=0
SET segmax=10
SET distmax=1
SET multiplier=1000
SET node=split
SET kernel=uniform

v.kernel --overwrite --verbose input=%input% net=%net% net_output=%net_output% radius=%radius% dsize=%dsize% segmax=%segmax% distmax=%distmax% multiplier=%multiplier% node=%node% kernel=%kernel%
v.out.ogr -sce input=V_KERNEL_OUTPUT dsn=. olayer=v_kernel format=ESRI_Shapefile type=line --overwrite --quiet
g.remove -f type=vector name=V_KERNEL_OUTPUT --quiet
``````
• I'm having the same problem! Did you ever find a solution? Jan 13, 2018 at 19:09
• I did not get this resolved. Eventually, I contacted the developer (Radim Blazek). His advice was to use a lower value for the segmax parameter. I used segmax=100, he said lower. I tried that and got slightly better results. However, it turned out, for my case, that a few false positives and negatives in the overall result wasn't really a problem. So I went with what I got. PS: The developer offered paid support. I looked at the C-code myself and tried to figure out myself how to improve but this was beyond my capabilities.
– JTh
Jan 15, 2018 at 7:06
• Ah thanks for this. I have tried this and used a lower segmax parameter but I don't think it has improved my results to be honest. Also I'm getting confused - for 'multiply the density result by this number' - how are you supposed to choose a number for this? If I don't type a number into this box, then my result isn't a density map... Jan 19, 2018 at 11:09
• I'm afraid I cannot help you much. I used the module v.kernel using several parameter combinations until I got something that seemed to represent the point densities along my network. The multiply parameter is needed in GRASS because the calculation is stored in the cat parameter and can only be integer. The multiplier helps in keeping the decimal precision that otherwise would be lost (truncated as integer). I suggest you contact the author of the module for further help: he responded swiftly in my case. The module has changed in GRASS 7.2. See edit for update.
– JTh
Jan 20, 2018 at 10:37