urbananalyst / dodgr Goto Github PK
View Code? Open in Web Editor NEWDistances on Directed Graphs in R
Home Page: https://urbananalyst.github.io/dodgr/
Distances on Directed Graphs in R
Home Page: https://urbananalyst.github.io/dodgr/
Following the sensible advice of the google C++ style guide, make all arguments passed by reference const
, which means making all (current) variable args pointers instead of reference objects.
Convert output of dodgr_dists()
for single points to polygonal isochrones and isodistances. Totally easy to do, and likely really useful for lots of applications, right @Robinlovelace @richardbeare?
@richardbeare: This is by way of an affirmative reponse to your email, which I'll reply to in further detail asap.
I just tried using compare_heaps
, but I got an error message
> compare_heaps (graph)
Error in matrix(pts, ncol = 1) :
'data' must be of a vector type, was 'NULL'
I looked into it and this seems to cause it. The object returned by dodgr_contract_graph
doesn't have a column contracted
. Is this a matter of just changing column contracted
to graph
or is there something more amiss?
Hi,
I played around with dodgr_dist to see how the geographical distances and walking distances calculated with dodgr_dist deviate. Normally all walking distances should be greater than or equal to the geographical distances. However, empirically dodgr_dist calculates distances that are shorter. Is it a data / osm problem? Or is my code wrong? Here is my code:
library(sf)
library(dodgr)
library(ggplot2)
library(sp)
#creates the graph for Essen
essen <- dodgr_streetnet("Essen, Germany")
graph <- weight_streetnet (essen, wt_profile = "foot")
#creates a rectangle as sample boundery
rec <- as(raster::extent(51.44, 51.475, 6.98, 7.06), "SpatialPolygons")
proj4string(rec) <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
e_forty <- fortify(rec)
#sample grid and points
grid <- spsample(e, n = 100, "regular")
plot(grid)
random <- spsample(e, n = 10, "random")
points(random)
from <- as.data.frame(coordinates(grid))
to <- as.data.frame(coordinates(random))
names(from) <- c("lat","lon")
names(to) <- c("lat","lon")
ggplot(graph, aes(x=from_lon, y=from_lat))+geom_segment(aes(xend = to_lon, yend= to_lat))+
geom_point(data = from,aes(lon, lat), col = "yellow")+
geom_point(data = to,aes(lon, lat), col = "red")
#network distances from grid points to sample points
net_dist <- dodgr_dists(graph, from = from, to = to)
#minimum network distance
min_net_dist <- apply(dodgr_dists(graph, from = from, to = to), 1,min)
#minimum geographical distance
min_geo_dist <- apply(spDists(as.matrix(from),as.matrix(to), longlat = T), 1, min)
from$diff <- min_net_dist - min_geo_dist
from$neg <- ifelse(diff > 0, 0,1)
ggplot(data = graph, aes(x = from_lon, y = from_lat))+geom_segment(aes(xend=to_lon, yend=to_lat))+
geom_point(data = from,aes(x = lon, y = lat, colour = diff, size = diff))+
scale_color_gradient2(low = "blue", high = "red")
ggplot(data = graph, aes(x = from_lon, y = from_lat))+geom_segment(aes(xend=to_lon, yend=to_lat))+
geom_point(data = from,aes(x = lon, y = lat, colour = as.factor(neg), size = diff))+
scale_color_discrete()
dodgr_paths cannot find routes that go along a single straight line, (i.e. only contain one edge in the graph)
Example:
library(sf)
library(dodgr)
# Make some lines
l1 = st_linestring(matrix(c(0,0,0,1), ncol = 2, byrow = T))
l2 = st_linestring(matrix(c(0,1,1,1), ncol = 2, byrow = T))
l3 = st_linestring(matrix(c(1,1,1,2), ncol = 2, byrow = T))
#make sf object
sfdf = st_sf(data.frame(id = 1:3, type = "road", geometry = st_sfc(list(l1,l2,l3))))
# make dodgr graph
weights = 1
names(weights) = "road"
graph = weight_streetnet(sfdf, type_col = "type", wt_profile = weights, id_col = "id")
paths = dodgr_paths(graph)
paths
This seems to be an inconsistency in how the results are returned. For example, the route from 1 to 4 is returned as 2, 3, 4 but the route from 1 to 2 is returned as character(0) rather than 2.
Perhaps the best solution would be to always return the start and endpoints of the path e.g.:
1-4 = 1,2,3,4
1-2 = 1,2
1-1 = 1
Coz binary queues are almost always best anyway, so will be much easier and cleaner to dump all the interanlly bunlded code and just use STL. It'll also be interesting to profile installed pacakge sizes for comparison.
I'm trying to find shortest paths, but get error:
Error in `*tmp*`[[i]] :
attempt to select less than one element in integerOneIndex
library(data.table)
library(dodgr)
dt <- data.table(from=c("a", "b", "c", "a"), to=c("b", "c", "d", "c"), dist=c(2, 2, 2, 2), weight=c(3, 3, 3, 3))
dp <- dodgr_paths(dt, from="a", to="d")
I might have misunderstood how dodgr works...
@karpfen here's one where you could maybe help out a lot if you wanted to. The dodgr
manuscript could - likely should - include an empirical section comparing performance for lots of different kinds of graphs (beyond just street networks. I just found the igraphdata
package which is perfect for the purpose, and igraph
is sufficiently standardised that it could be used as the sole benchmark. dodgr
already has the compare_heaps()
function to do the testing, so it'd just be a matter of running all the graphs though the tests. This would probably best reside (for the moment) in a second vignette.
I'm getting an error when attempting to use weight_streetnet
Error in which(outer(xy_from$from_lon, xy_indx$x, "==") & outer(xy_from$from_lat, : long vectors not supported yet: ../include/Rinlinedfuns.h:138
Example:
library(sf)
library(dodgr)
file = "https://raw.githubusercontent.com/mem48/UK2GTFS/master/data/railways_simplified.geojson"
rail = st_read(file)
wts = 1
names(wts) = "rail"
net = weight_streetnet(rail, type_col = "railway", wt_profile = wts, id_col = "id")
The file is of the UK rail network and has been heavily simplified to a 2 MB file of about 2300 lines.
The function runs for a while and uses an extremely large amount of RAM (about 65GB) before failing. This is not a hardware problem as I have plenty of RAM to spare. It is also not a data problem because, subsets do work, e.g.
# Works
rail2 = rail[1:2000,]
graph = weight_streetnet(rail2, type_col = "railway", wt_profile = wts, id_col = "id")
# Also Works
rail3 = rail[2000:nrow(rail),]
graph = weight_streetnet(rail3, type_col = "railway", wt_profile = wts, id_col = "id")
It seems that when using the weight_streetnet
function dodgr does not join the lines into a complete network but instead just many disconnected subgraphs.
From the vignette
colnm <- "formOfWay"
wts <- c (0.1, 0.2, 0.8, 1)
names (wts) <- unique (os_roads_bristol [[colnm]])
net <- weight_streetnet (os_roads_bristol, wt_profile = wts,
type_col = colnm, id_col = "identifier")
Analysis
nrow(os_roads_bristol) #29 lines
length(unique(net$component)) #29 discrete subgraphs
Try routing
from <- net$from_id[1:2]
to <- net$to_id[406]
dp <- dodgr_paths (net, from = from, to = to)
dodgr fails to find any routes
make_compact_graph
works, but is not yet implemented to enable routing vertices to be re-inserted into the compact graph.
Dump all usages of dodgr_convert_graph()
in favour of just discerning the index positions and passing the full graph along with these to the Rcpp
routines. This will be more flexible and faster too.
thanks @karpfen! this must be implemented.
Lots of routines currently rely on osm_id_t
vertices - these should be changed to generic types, and maybe an extra set of OSM-specific routines farmed off to a graph-osm.cpp
file
to include dodgr_paths()
and dodgr_flows()
, and also update the pkgdown
site
Cheap ruler is explained in this blog post. Their cheap method for intra-urban distances would likely provide a nifty speed boost
To enable flows to be routed through contracted graphs, but re-allocated to full graphs
A Feature request:
When using the from
and to
variables in dodgr_paths
it is not possible to specify a defined list of paths to calculate. Example pseudo code:
from = c(1,2,3)
to = c(4,5,6)
dp = dodgr_paths(graph, from, to)
This will return 9 routes:
1-4
1-5
1-6
2-4
2-5
2-6
3-4
3-5
3-6
It would be useful to have a by_element
variable, similar to how sf::st_distance
handles this problem that if true would return just:
1-4
2-5
3-6
For small examples, this is trivial to subset out the desired results, but as we are calculating n^2 paths rather than the required n paths this rapidly becomes a large problem.
Currently just extracts a bounding box and returns that; just need to
osmdata::trim_osmdata()
to trim the resultant network back to the shape of the original polygon.See examples in r4trans-april18
repo
All current tests are on consistent osmdata
structures. Tests have to be extended to consider other potential types of data, especially other types of street networks: splanr::routes_fast_sf
Hello,
I have attended the R for Transport Planning in Leeds with @Robinlovelace, and saw you via Skype when you talked about your dodgr package. After testing your sample data, I attempted to apply data of my own - OD_seoul_2014_long.csv in https://github.com/mrsensible/leedsR/. You can possibly download it. The data looks something like this:
origin.code.14 destin.2014 ODfrac
1 1101053 1101053 0.077
2 1101054 1101053 0.059
3 1101055 1101053 0.223
4 1101056 1101053 0.275
5 1101057 1101053 0.077
6 1101058 1101053 0.034
And converted the format into a character:
> str(od.seoul)
'data.frame': 524064 obs. of 3 variables:
$ origin.code.14: chr "1101053" "1101054" "1101055" "1101056" ...
$ destin.2014 : chr "1101053" "1101053" "1101053" "1101053" ...
$ ODfrac : chr "0.077" "0.059" "0.223" "0.275" ...
But, after I execute dodgr_dists(graph = od.seoul, from = origin.code.14, to = destin.2014)
it gives me an error notice which looks something like this:
> dodgr_dists(graph = od.seoul, from = origin.code.14, to = destin.2014)
Error in find_to_id_col(graph) :
Unable to determine column with ID of from vertices
Could you help me solve this problem? Many thanks -Hyesop-
to show how dodgr
handles non-OSM street networks. @Robinlovelace wanna PR this? Just put some data there, and I should be able to take care of the rest.
Following on from @rafapereirabr's SO question, it would be very useful for dodgr
to incorporate the ability to insert new points in a network. Current routing can accept arbitrary points, but these are simply mapped to nearest network points and then forgotten. Incorporation of new points would involve modification of the underlying network, so a network with an edge between A and B would be modified through calling
insert_point (network, x, y)
to
A -> (new point with hashed id) -> B
or,
> insert_point (network, x, y, "C")
# A -> C -> B
The points A and B could be automatically identified as the nearest two points, yet this may not necessarily be what is desired. It will likely be necessary to have an option to override this default behaviour that would then graphically show the default, yet enable other options to be specified.
@rafapereirabr: this might take a while to implement, because it will be more appropriately incorporated within the soon-to-appear-on-cran silicate
, and associated sc
, rather than sf
or sp
representations. This whole issue is therefore likely to first be shifted to silicate
and ultimately resolved there. cc @mdsumner
> graph <- weight_streetnet (hampi)
> vt <- dodgr_vertices (graph)
> from <- sample (vt$id, size = 10)
> graph$from_lon <- graph$from_lat <- graph$to_lon <- graph$to_lat <- NULL
> d <- dodgr_dists (graph, from = from, to = from)
Error in find_spatial_cols(graph) :
Graph appears to be spatial yet unable to extract coordinates.
Coz the main C++ code is a loop. Easy to do; just has to be done in C++ and not in R
Hi Mark,
I'm trying to install the development version of dodgr
so I can use the functions you recommended me here. However, I keep getting this error and I don't know really to go around it. Have you seen this before?
Here is my R session:
> sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Matrix products: default
locale:
[1] LC_COLLATE=Portuguese_Brazil.1252 LC_CTYPE=Portuguese_Brazil.1252 LC_MONETARY=Portuguese_Brazil.1252
[4] LC_NUMERIC=C LC_TIME=Portuguese_Brazil.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] RevoUtils_10.0.6 RevoUtilsMath_10.0.1
loaded via a namespace (and not attached):
[1] compiler_3.4.2 tools_3.4.2
And here is the error I'm getting:
> devtools::install_github("ATFutures/dodgr")
Downloading GitHub repo ATFutures/dodgr@master
from URL https://api.github.com/repos/ATFutures/dodgr/zipball/master
Installing dodgr
"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/bin/x64/R" --no-site-file --no-environ --no-save --no-restore --quiet CMD INSTALL \
"C:/Users/rafa/AppData/Local/Temp/RtmpUj1K7r/devtools32607530269d/ATFutures-dodgr-dc6d87a" \
--library="C:/Users/rafa/Documents/R/win-library/3.4" --install-tests
* installing *source* package 'dodgr' ...
** libs
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c RcppExports.cpp -o RcppExports.o
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c dgraph.cpp -o dgraph.o
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c dijkstra.cpp -o dijkstra.o
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c dodgr-to-sf.cpp -o dodgr-to-sf.o
dodgr-to-sf.cpp: In function 'size_t make_edge_name_set(std::unordered_set<std::basic_string<char> >&, const CharacterVector&)':
dodgr-to-sf.cpp:9:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 0; i < new_edges.size (); i++)
^
dodgr-to-sf.cpp: In function 'void make_edge_name_vec(size_t, const CharacterVector&, std::vector<std::basic_string<char> >&)':
dodgr-to-sf.cpp:26:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 1; i < new_edges.size (); i++)
^
dodgr-to-sf.cpp: In function 'size_t get_edgevec_sizes(size_t, const CharacterVector&, std::vector<long long unsigned int>&)':
dodgr-to-sf.cpp:44:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 1; i < new_edges.size (); i++)
^
dodgr-to-sf.cpp: In function 'void get_edge_to_vert_maps(const std::vector<long long unsigned int>&, const DataFrame&, const CharacterVector&, const CharacterVector&, const std::vector<std::basic_string<char> >&, std::unordered_map<std::basic_string<char>, std::vector<std::basic_string<char> > >&, std::unordered_map<std::basic_string<char>, std::vector<std::basic_string<char> > >&)':
dodgr-to-sf.cpp:85:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 1; i < new_edges.size (); i++)
^
dodgr-to-sf.cpp: In function 'size_t count_non_contracted_edges(const CharacterVector&, std::unordered_set<std::basic_string<char> >&)':
dodgr-to-sf.cpp:165:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 0; i < contr_edges.size (); i++)
^
dodgr-to-sf.cpp: In function 'void append_nc_edges(size_t, const DataFrame&, std::unordered_set<std::basic_string<char> >&, std::vector<std::basic_string<char> >&, const List&, std::vector<std::basic_string<char> >&, Rcpp::List&)':
dodgr-to-sf.cpp:191:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 0; i < graph_contr.nrow (); i++)
^
dodgr-to-sf.cpp:207:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 0; i < edge_sequences_contr.size (); i++)
^
dodgr-to-sf.cpp:212:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 0; i < edge_sequences_new.size (); i++)
^
dodgr-to-sf.cpp: In function 'void xy_to_sf(const DataFrame&, const List&, const std::vector<std::basic_string<char> >&, Rcpp::List&)':
dodgr-to-sf.cpp:259:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t i = 0; i < idf_r.size (); i++)
^
c:/Rtools/mingw_64/bin/gcc -m64 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -O2 -Wall -std=gnu99 -mtune=core2 -c dodgr_init.c -o dodgr_init.o
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c graph-contract.cpp -o graph-contract.o
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c graph-sample.cpp -o graph-sample.o
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c graph.cpp -o graph.o
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c run_sp.cpp -o run_sp.o
run_sp.cpp: In member function 'virtual void OneDist::operator()(std::size_t, std::size_t)':
run_sp.cpp:86:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t j = 0; j < toi.size (); j++)
^
run_sp.cpp: In member function 'virtual void OneFlow::operator()(std::size_t, std::size_t)':
run_sp.cpp:507:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (size_t j = 0; j < toi.size (); j++)
^
c:/Rtools/mingw_64/bin/g++ -m64 -std=gnu++11 -I"C:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/include" -DNDEBUG -I"C:/Users/rafa/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/include" -I"C:/swarm/workspace/External-R-3.4.2/vendor/extsoft/include" -DRCPP_PARALLEL_USE_TBB=1 -O2 -Wall -mtune=core2 -c sf-as-network.cpp -o sf-as-network.o
sf-as-network.cpp: In member function 'virtual void OnePointIndex::operator()(std::size_t, std::size_t)':
sf-as-network.cpp:210:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int j = 0; j < nxy; j++)
^
c:/Rtools/mingw_64/bin/g++ -m64 -shared -s -static-libgcc -o dodgr.dll tmp.def RcppExports.o dgraph.o dijkstra.o dodgr-to-sf.o dodgr_init.o graph-contract.o graph-sample.o graph.o run_sp.o sf-as-network.o -LC:/Users/rafa/Documents/R/win-library/3.4/RcppParallel/lib/x64 -ltbb -ltbbmalloc -LC:/swarm/workspace/External-R-3.4.2/vendor/extsoft/lib/x64 -LC:/swarm/workspace/External-R-3.4.2/vendor/extsoft/lib -LC:/PROGRA~1/MICROS~1/ROPEN~1/R-34~1.2/bin/x64 -lR
run_sp.o:run_sp.cpp:(.text$_ZNK5HeapDI5FHeapE11newInstanceEj[_ZNK5HeapDI5FHeapE11newInstanceEj]+0x1b): undefined reference to `FHeap::FHeap(unsigned int)'
run_sp.o:run_sp.cpp:(.text$_ZNK5HeapDI9RadixHeapE11newInstanceEj[_ZNK5HeapDI9RadixHeapE11newInstanceEj]+0x1b): undefined reference to `RadixHeap::RadixHeap(unsigned int)'
run_sp.o:run_sp.cpp:(.text$_ZNK5HeapDI10TriHeapExtE11newInstanceEj[_ZNK5HeapDI10TriHeapExtE11newInstanceEj]+0x1b): undefined reference to `TriHeapExt::TriHeapExt(unsigned int)'
run_sp.o:run_sp.cpp:(.text$_ZNK5HeapDI7TriHeapE11newInstanceEj[_ZNK5HeapDI7TriHeapE11newInstanceEj]+0x1b): undefined reference to `TriHeap::TriHeap(unsigned int)'
run_sp.o:run_sp.cpp:(.text$_ZNK5HeapDI6Heap23E11newInstanceEj[_ZNK5HeapDI6Heap23E11newInstanceEj]+0x1b): undefined reference to `Heap23::Heap23(unsigned int)'
run_sp.o:run_sp.cpp:(.text$_ZNK5HeapDI5BHeapE11newInstanceEj[_ZNK5HeapDI5BHeapE11newInstanceEj]+0x1b): undefined reference to `BHeap::BHeap(unsigned int)'
collect2.exe: error: ld returned 1 exit status
no DLL was created
ERROR: compilation failed for package 'dodgr'
* removing 'C:/Users/rafa/Documents/R/win-library/3.4/dodgr'
Installation failed: Command failed (1)
Because it returns an object of class:
"sfc_LINESTRING" "sfc"
Suggestions: rename it to dodgr_sfc
and create a new function dodgr_sf
that returns an object of class sf
.
I'm having problems getting paths from dodgr_paths()
Example:
colnm <- "formOfWay"
wts <- c (0.1, 0.2, 0.8, 1)
names (wts) <- unique (os_roads_bristol [[colnm]])
net <- weight_streetnet (os_roads_bristol, wt_profile = wts,
type_col = colnm, id_col = "identifier")
from <- net$from_id[1:2]
to <- net$to_id[6:7]
dp <- dodgr_paths (net, from = from, to = to)
dp
# result
#$`374`
#$`374`$`374-374`
#character(0)
dodgr fails to find any paths
I have observed three types of error:
Error in dimnames(x) <- dn : length of 'dimnames' [2] not equal to array extent
Example:
from <- net$from_id[1:2]
to <- net$to_id[406:408]
dp <- dodgr_paths (net, from = from, to = to)
Example:
from <- net$from_id[1:2]
to <- net$to_id[406:407]
dp <- dodgr_paths (net, from = from, to = to)
verts <- dodgr_vertices (net)
path1 <- verts [match (dp [[1]] [[1]], verts$id), ]
points <- verts [match (as.character(c(from,to)), verts$id), ]
plot(path1$x,path1$y)
points(points$x, points$y, col = "red", bg = "red", pch = 21)
So that output of dodgr
can be used directly in osmprob
. cc @karpfen
This is currently not directly possible; see #31
The google C++ style guide is a good argument against usage of unsigned int
and the like. Modify all src/
code to follow this.
So flows can be re- allocated back on to original ways This is also related to #21, because that will automatically happen when original graph form is retained in both contracted graphs and flow graphs.
A feature request:
For a weighting profile for railways taken from the OSM, which respects the max speed variable and the railway variable.
break current dodgr_flows()
fn into dodgr_flows_aggregate()
and dodgr_flows_disperse()
functions, where the latter is single origin -> all destinations according to user-specified functional form for dispersal
I think there are ways to allow dodgr to work more easily - none of this is an 'engineering' problem but a 'user friendliness' issue I think - hope this is makes sense and is useful, an outgrowth of ropensci/stplanr#261
rnet_decompose <- function(l) {
if(is.null(l$highway)) l$highway <- "tertiary"
g <- dodgr::weight_streetnet(sf_lines = l, wt_profile = 1)
}
# testing
library(stplanr)
library(dodgr)
library(sf)
#> Linking to GEOS 3.5.1, GDAL 2.2.2, proj.4 4.9.2
class(hampi)
#> [1] "sf" "data.frame"
hampi # error...
#> Error in .subset2(x, i, exact = exact): attempt to select less than one element in get1index
hampi_sf = st_sf(hampi)
#> Error in .subset2(x, i, exact = exact): attempt to select less than one element in get1index
# weight_streetnet(hampi) # works
os_roads_bristol
#> Simple feature collection with 29 features and 19 fields
#> geometry type: LINESTRING
#> dimension: XY
#> bbox: xmin: -2.70732 ymin: 51.47842 xmax: -2.616046 ymax: 51.56824
#> epsg (SRID): 4326
#> proj4string: +proj=longlat +datum=WGS84 +no_defs
#> # A tibble: 29 x 20
#> fictitious identifier class roadNumber name1 name1_lang name2
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 false 6E48BDC8-D330-4B26… Motor… M49 <NA> <NA> <NA>
#> 2 false A2562BED-60E6-4FCF… Motor… M5 <NA> <NA> <NA>
#> 3 false 6DA7405F-E2DA-4052… Motor… M49 <NA> <NA> <NA>
#> 4 false CB58D923-3EB8-45E4… Motor… M5 <NA> <NA> <NA>
#> 5 false C9D6EDEB-5227-43F5… Motor… M49 <NA> <NA> <NA>
#> 6 false 41589DA6-0068-4030… Motor… M49 <NA> <NA> <NA>
#> 7 false E712E6EE-6661-467E… Motor… M5 <NA> <NA> <NA>
#> 8 false 86D187FE-5519-475F… Motor… M49 <NA> <NA> <NA>
#> 9 false 2AB96D1E-CD50-4BAA… Motor… M5 <NA> <NA> <NA>
#> 10 false E90FDAB3-1F07-431A… Motor… M5 <NA> <NA> <NA>
#> # ... with 19 more rows, and 13 more variables: name2_lang <chr>,
#> # formOfWay <chr>, length <int>, primary <chr>, trunkRoad <chr>,
#> # loop <chr>, startNode <chr>, endNode <chr>, structure <chr>,
#> # nameTOID <chr>, numberTOID <chr>, function. <chr>,
#> # geometry <LINESTRING [°]>
plot(os_roads_bristol)
#> Warning: plotting the first 10 out of 19 attributes; use max.plot = 19 to
#> plot all
# from ?os_roads_open
colnm <- "formOfWay" # name of column used to determine weights
wts <- c (0.1, 0.2, 0.8, 1)
names (wts) <- unique (os_roads_bristol [[colnm]])
os_roads_bristol$highway = "Motorway"
weight_streetnet(os_roads_bristol) # fails wih unhelpful error msg
#> Error in weight_streetnet(os_roads_bristol): sf_lines must be class "sf" and have highway and geometry columns
net <- weight_streetnet (os_roads_bristol, wt_profile = wts, # fails wih unhelpful error msg
type_col = colnm, id_col = "identifier")
#> Error in rcpp_sf_as_network(sf_lines, pr = wt_profile): sf_lines have no geometry component
os_roads_bristol$highway <- NULL
net <- weight_streetnet (os_roads_bristol, wt_profile = wts, # works!!!!
type_col = colnm, id_col = "identifier")
# another example...
data_dir <- system.file("extdata", package = "stplanr")
unzip(file.path(data_dir, "sydroads.zip"), exdir = tempdir())
sydroads <- read_sf(tempdir(), "roads")
plot(sydroads$geometry)
names(sydroads)
#> [1] "osm_id" "name" "ref" "type" "oneway" "bridge"
#> [7] "maxspeed" "geometry"
colnm <- "type"
road_types <- unique (sydroads[[colnm]])
wts <- rep(1, length(road_types))
names (wts) <- road_types
weight_streetnet(sydroads) # fails
#> Error in weight_streetnet(sydroads): sf_lines must be class "sf" and have highway and geometry columns
net1 <- weight_streetnet(sydroads, type_col = "type") # works?
net <- weight_streetnet (sydroads, wt_profile = wts,
type_col = colnm, id_col = "osm_id")
devtools::session_info()
#> Session info -------------------------------------------------------------
#> setting value
#> version R version 3.5.0 (2018-04-23)
#> system x86_64, linux-gnu
#> ui X11
#> language en_GB:en
#> collate en_GB.UTF-8
#> tz Europe/London
#> date 2018-06-08
#> Packages -----------------------------------------------------------------
#> package * version date source
#> assertthat 0.2.0 2017-04-11 cran (@0.2.0)
#> backports 1.1.2 2017-12-13 CRAN (R 3.5.0)
#> base * 3.5.0 2018-04-23 local
#> bindr 0.1.1 2018-03-13 cran (@0.1.1)
#> bindrcpp 0.2.2 2018-03-29 cran (@0.2.2)
#> class 7.3-14 2015-08-30 cran (@7.3-14)
#> classInt 0.2-3 2018-04-16 cran (@0.2-3)
#> cli 1.0.0 2017-11-05 cran (@1.0.0)
#> compiler 3.5.0 2018-04-23 local
#> crayon 1.3.4 2017-09-16 CRAN (R 3.5.0)
#> curl 3.2 2018-03-28 cran (@3.2)
#> datasets * 3.5.0 2018-04-23 local
#> DBI 1.0.0 2018-05-02 cran (@1.0.0)
#> devtools 1.13.5 2018-02-18 CRAN (R 3.5.0)
#> digest 0.6.15 2018-01-28 CRAN (R 3.5.0)
#> dodgr * 0.0.3 2017-10-30 CRAN (R 3.5.0)
#> dplyr 0.7.5 2018-05-19 cran (@0.7.5)
#> e1071 1.6-8 2017-02-02 cran (@1.6-8)
#> evaluate 0.10 2016-10-11 CRAN (R 3.3.2)
#> foreign 0.8-70 2018-04-23 CRAN (R 3.5.0)
#> geosphere 1.5-7 2017-11-05 cran (@1.5-7)
#> glue 1.2.0 2017-10-29 CRAN (R 3.5.0)
#> graphics * 3.5.0 2018-04-23 local
#> grDevices * 3.5.0 2018-04-23 local
#> grid 3.5.0 2018-04-23 local
#> htmltools 0.3.6 2017-04-28 CRAN (R 3.5.0)
#> httr 1.3.1 2017-08-20 cran (@1.3.1)
#> igraph 1.2.1 2018-03-10 cran (@1.2.1)
#> jsonlite 1.5 2017-06-01 cran (@1.5)
#> knitr 1.20 2018-02-20 CRAN (R 3.5.0)
#> lattice 0.20-35 2017-03-25 CRAN (R 3.5.0)
#> lubridate 1.7.4 2018-04-11 cran (@1.7.4)
#> magrittr 1.5 2014-11-22 CRAN (R 3.3.2)
#> maptools 0.9-2 2017-03-25 CRAN (R 3.5.0)
#> memoise 1.1.0 2017-04-21 CRAN (R 3.5.0)
#> methods * 3.5.0 2018-04-23 local
#> mime 0.5 2016-07-07 CRAN (R 3.5.0)
#> openxlsx 4.1.0 2018-05-26 cran (@4.1.0)
#> osmdata 0.0.7 2018-05-17 CRAN (R 3.5.0)
#> pillar 1.2.3 2018-05-25 cran (@1.2.3)
#> pkgconfig 2.0.1 2017-03-21 cran (@2.0.1)
#> purrr 0.2.5 2018-05-29 cran (@0.2.5)
#> R.methodsS3 1.7.1 2016-02-16 cran (@1.7.1)
#> R.oo 1.22.0 2018-04-22 cran (@1.22.0)
#> R.utils 2.6.0 2017-11-05 cran (@2.6.0)
#> R6 2.2.2 2017-06-17 cran (@2.2.2)
#> raster 2.6-7 2017-11-13 cran (@2.6-7)
#> rbenchmark 1.0.0 2012-08-30 CRAN (R 3.5.0)
#> Rcpp 0.12.17 2018-05-18 CRAN (R 3.5.0)
#> rgdal 1.3-2 2018-06-08 CRAN (R 3.5.0)
#> rgeos 0.3-27 2018-06-01 cran (@0.3-27)
#> rlang 0.2.1 2018-05-30 cran (@0.2.1)
#> rmarkdown 1.9 2018-03-01 CRAN (R 3.5.0)
#> rprojroot 1.3-2 2018-01-03 CRAN (R 3.5.0)
#> rvest 0.3.2 2016-06-17 CRAN (R 3.3.2)
#> sf * 0.6-3 2018-05-17 cran (@0.6-3)
#> sp 1.3-1 2018-06-05 CRAN (R 3.5.0)
#> spData 0.2.8.9 2018-06-03 Github (nowosad/spData@7b53933)
#> spDataLarge 0.2.6.5 2018-06-02 Github (nowosad/spDataLarge@bc058ad)
#> stats * 3.5.0 2018-04-23 local
#> stplanr * 0.2.5 2018-06-08 local
#> stringi 1.2.2 2018-05-02 CRAN (R 3.5.0)
#> stringr 1.3.1 2018-05-10 CRAN (R 3.5.0)
#> tibble 1.4.2 2018-01-22 cran (@1.4.2)
#> tidyselect 0.2.4 2018-02-26 cran (@0.2.4)
#> tools 3.5.0 2018-04-23 local
#> udunits2 0.13 2016-11-17 cran (@0.13)
#> units 0.5-1 2018-01-08 cran (@0.5-1)
#> utf8 1.1.4 2018-05-24 cran (@1.1.4)
#> utils * 3.5.0 2018-04-23 local
#> withr 2.1.2 2018-03-15 CRAN (R 3.5.0)
#> xml2 1.2.0 2018-01-24 CRAN (R 3.5.0)
#> yaml 2.1.19 2018-05-01 CRAN (R 3.5.0)
#> zip 1.0.0 2017-04-25 cran (@1.0.0)
At the moment this presumes a continuous 1-indexed value. This needs to be modified for arbitrary edge_id values converted to std::string
.
dodgr_to_sf
current just returns geometry, leaving the user to match the contracted geometry onto the flow data from the full (non-contracted) data.frame
. The dodgr_to_sf()
function should be modified to return a list of
_sfc
geometry as in current form; along wihtdata.frame
containing all of the corresponding data re-matched onto the contracted geometryHallo,
I am not sure what the exact unit (kilometre, miles?) of the output of dodgr_dists() is and if it's working correctly. I tried to verify the results from dodgr_dists() with googlemaps and there are hugh differences I can't explain. Please, try the following code to reproduce my Problem.
library(dodgr)
library(ggmap)essen <- dodgr_streetnet("Essen, Germany")
graph <- weight_streetnet(essen)mainstation <- geocode("Hauptbahnhof, Essen, Germany")
mall <- geocode("Limbeckerplatz 1, Essen, Germany")names(mainstation) <- c("x","y")
names(mall) <- c("x","y")mainstation <- as.data.frame(mainstation)
mall <- as.data.frame(mall)d <- dodgr_dists(graph, from = mainstation,to = mall, wt_profile = "foot")
mapdist(from = c("Hauptbahnhof, Essen, Germany"), to = c("Limbeckerplatz 1, Essen, Germany"), mode = "walking")
address1 <- geocode("Brigittastrasse 25, Essen, Germany")
address2 <- geocode("Kronprinzenstrasse 6, Essen, Germany")names(address1) <- c("x","y")
names(address2) <- c("x","y")d <- dodgr_dists(graph, from = address1,to = address2, wt_profile = "foot")
mapdist(from = c("Brigittastrasse 25, Essen, Germany"), to = c("Kronprinzenstrasse 6, Essen, Germany"), mode = "walking")
address1 <- geocode("Engelsbecke 24, Essen, Germany")
address2 <- geocode("Holunderweg 10, Essen, Germany")names(address1) <- c("x","y")
names(address2) <- c("x","y")d <- dodgr_dists(graph, from = address1,to = address2, wt_profile = "foot")
mapdist(from = c("Engelsbecke 24, Essen, Germany"), to = c("Holunderweg 10, Essen, Germany"), mode = "walking")
once this issue has been fixed.
Similar to #39, and for same reasons
Current does not actually work
The final test for lengths of paths between edges and vertices no longer works. The latter should generate paths that have lengths one greater than the former, yet they don't for cases in which vertex paths have lengths of only one. This naturally doesn't make sense, because no paths should have lengths of only one - check and fix.
This would be useful to easily apply igraph
functionality to dodgr
street networks. See this python osmnx
example for a great example of the kinds of analyses that could then be immediately done. See also #41
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.