[R-sig-Geo] [FORGED] Create a Spatial Weight Matrix based on road distance

Roger Bivand Roger@B|v@nd @end|ng |rom nhh@no
Mon Jun 24 09:57:49 CEST 2019


On Mon, 24 Jun 2019, Rolando Valdez wrote:

> Dear Andres,
>
> I could follow an example provided with the package, it was a little bit
> simple, however, I got this message:
>
>> dists <- osrmTable(loc = muns13, measure = "duration")
> The OSRM server returned an error:
> Error: The public OSRM API does not allow results with a number of
> durations
> higher than 10000. Ask for fewer durations or use your own server and set
> its
> --max-table-size option.
>
> My sample size is 2,457

Were you asking for the whole nx(n-1)/2 set of durations in one run? You 
see that the API limits the number of interactions (possibly by time and 
by unique IP number). So you need to reduce the number of queries. If you 
are going to impose a distance threshold anyway, you can do that using the 
Great Circle (not Euclidean) distances between your geographical 
coordinates and dnearneigh(), and step through the nb list object with 
src= being the data frame of the observation coordinates, and dest= the 
data frame of the neighbours' coordinates.

library(sf)
nc <- st_read(system.file("shapes/sids.shp", package="spData")[1], 
quiet=TRUE)
st_crs(nc) <- "+proj=longlat +datum=NAD27"
nc1 <- st_transform(nc, 32019)
nc2 <- st_centroid(nc1, of_largest_polygon=TRUE)
nc3 <- st_transform(nc2, 4326)
crds <- st_coordinates(st_geometry(nc3))
df <- data.frame(id=nc3$FIPSNO, long=crds[,1], lat=crds[,2])
library(spdep)
nb <- dnearneigh(crds, 0, 50, longlat=TRUE)
library(osrm)
res <- vector(mode="list", length=nrow(df))
for (i in seq(along=res)) res[[i]] <- osrmTable(src=df[i,],
  dst=df[nb[[i]],], measure = "duration")
res1 <- lapply(res, function(x) 10/x$duration)
lw <- nb2listw(nb, glist=res1, style="B")

gives general spatial weights based on 10/# minutes travel time between 
county centroids (centroids calculated from projected coordinates), for 
county centroids closer than 50 km measured by Great Circle.

In your case, you may need to split the for() loop into portions of 
cumsum(card(nb)) of less than the limit. If durations are symmetric, 
you could also halve the query count by taking only neighbour ids > i, 
but you'd have to fold them back afterwards. You also wanted to categorise 
the durations into 0,1, which you could do with lapply() instead of using 
inverse durations.

Hope this helps,

Roger

>
> El vie., 21 de jun. de 2019 a la(s) 02:53, Andres Diaz Loaiza (
> madiazl using gmail.com) escribió:
>
>> Dear Rolando,
>>
>> The advantage of using Open Street Maps engine is that you can give the
>> travel option. This means you can select whether are you traveling by bike,
>> car or walking. The previous approach didn't consider this topic. For this,
>> you should have added a vector layer depending on your position of the
>> street you can take (or not). Open Street Maps project allow you two
>> options: a service in which you give your current position, the position
>> you want to reach and your transport method (giving you back the fastest
>> route). Or the option to download the engine/algorithm compile by yourself
>> (if I am not wrong is made in C or python) and then you can make your own
>> calculation at your own computer. For the first option, the package OSRM is
>> an interface in which send a request to the OSM web page and wait for an
>> answer. With this method, you can send a couple of request at the same time
>> but no to many (you should read the manual for this). Of course, also will
>> depend on whether the OSM server is down or not (or busy).
>>
>> I have to say that I used some years ago this app and nowadays I know that
>> for some cities OSM has more streets reported than the same google maps.
>> Also is an open project and they let you download their data for free,
>> contrary to what google maps do.
>>
>> All the best,
>>
>>
>> Andres
>>
>> El vie., 21 jun. 2019 a las 4:30, Adrian Baddeley (<
>> adrian.baddeley using curtin.edu.au>) escribió:
>>
>>> Rather than converting an object of class 'SpatialLines' or
>>> 'SpatialLinesDataFrame' to the spatstat class 'psp' and then converting it
>>> to the spatstat class 'linnet', it is safer and more efficient to convert
>>> the SpatialLines* object directly to class linnet using
>>> as.linnet.SpatialLinesDataFrame() from the package 'maptools'.
>>>
>>>
>>> Prof Adrian Baddeley DSc FAA
>>>
>>> John Curtin Distinguished Professor
>>>
>>> Department of Mathematics and Statistics
>>>
>>> Curtin University, Perth, Western Australia
>>>
>>>
>>> ________________________________
>>> From: Rolf Turner <r.turner using auckland.ac.nz>
>>> Sent: Friday, 21 June 2019 10:08 AM
>>> To: Rolando Valdez
>>> Cc: r-sig-geo using r-project.org; Adrian Baddeley; Ege Rubak
>>> Subject: Re: [FORGED] [R-sig-Geo] Create a Spatial Weight Matrix based on
>>> road distance
>>>
>>>
>>> On 21/06/19 12:26 PM, Rolando Valdez wrote:
>>>
>>>> Dear community,
>>>>
>>>> Is there any way to create a spatial weight matrix based on road
>>> distance?
>>>> I am trying to use the road distance between two points instead of
>>>> euclidean distance.
>>>>
>>>> I've seen that there is a package named osrm. Can anyone give some
>>> advice?
>>>
>>> I don't know anything about "osrm".  Calculating "road distances" can be
>>> done in the spatstat package reasonably easily, if you take the trouble
>>> to represent your collection of roads as a "linnet" object.
>>>
>>> Given that you have done so, suppose that your linnet object is "L" and
>>> that you have vectors "x" and "y" specifying the points on L (i.e. on
>>> your roads) between which you want to know the distances.
>>>
>>> Do:
>>>
>>>      X    <- lpp(data.frame(x=x,y=y),L)
>>>      dMat <- pairdist(X)
>>>
>>> The object "dMat" is a (symmetric) square matrix; dMat[i,j] is the
>>> distance between point i and point j.  (Of course the diagonal entries
>>> are all 0.)
>>>
>>> If your collection of roads is specified by means of a shapefile,
>>> vignette("shapefiles") will tell you how to turn this collection into a
>>> "psp" ("planar segment pattern") object; the function (method)
>>> as.linnet.psp() can then be used to turn the "psp" object into a
>>> "linnet" object.
>>>
>>> HTH
>>>
>>> cheers,
>>>
>>> Rolf Turner
>>>
>>> --
>>> Honorary Research Fellow
>>> Department of Statistics
>>> University of Auckland
>>> Phone: +64-9-373-7599 ext. 88276
>>>
>>>         [[alternative HTML version deleted]]
>>>
>>> _______________________________________________
>>> R-sig-Geo mailing list
>>> R-sig-Geo using r-project.org
>>> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>>>
>>
>>
>> --
>> Andrés D.
>>
>
>
>

-- 
Roger Bivand
Department of Economics, Norwegian School of Economics,
Helleveien 30, N-5045 Bergen, Norway.
voice: +47 55 95 93 55; e-mail: Roger.Bivand using nhh.no
https://orcid.org/0000-0003-2392-6140
https://scholar.google.no/citations?user=AWeghB0AAAAJ&hl=en


More information about the R-sig-Geo mailing list