-
Notifications
You must be signed in to change notification settings - Fork 2
/
routesRandomiser.R
139 lines (110 loc) · 5.2 KB
/
routesRandomiser.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#Pick random points inside shapefile polygon
#Use Google distance matrix API to fetch network distance/time and addresses
#https://developers.google.com/maps/documentation/distancematrix/
#Store and save results as CSV
library(rgdal)
library(rgeos)
library(httr)
library(jsonlite)
#Load properties file
#Nabbed from http://stackoverflow.com/questions/13681310/reading-configuration-from-text-file
# myProp <- read.table("config.txt", header=FALSE, sep="=", row.names=1, strip.white=TRUE, na.strings="NA", stringsAsFactors=FALSE)
# myProp <- setNames(myProp[,1],row.names(myProp))
# myProp["dateOfLastLimitBreach"]
#record of failed calls
fail = 0
#Base URL, will knock query together below
testURL <- "http://maps.googleapis.com/maps/api/distancematrix/json"
#Use single shapefile of Great Britain
gbmerge <- readOGR(dsn="GB_merged", "GB_merged")
#Store the points
#Number of origin-destination pairs to create and fetch
#Note there's a pause of at least 0.2 seconds between each
#so getting >2000 of your daily google API allowance
#Might be around 7 minutes
#The csv won't be saved until the end of the process
#Job: add option to save regularly so's not to risk wasting API call limit
#DAILY ALLOWANCE IS 2500.
pairNum = 2000
#http://casoilresource.lawr.ucdavis.edu/drupal/book/export/html/644
#sp package has specific tool for spatial sampling within polygons. Hooray!
randomPointOrigins <- spsample(gbmerge, n=pairNum, type='random')
randomPointDestinations <- spsample(gbmerge, n=pairNum, type='random')
#In case you wanna see em
#plot(gbmerge); points(randomPointDestinations, col='red', pch=3, cex=0.5); points(randomPointOrigins, col='blue', pch=3, cex=0.5)
#convert to lat long in prep for google query
randomPointOrigins <- spTransform(randomPointOrigins, CRS("+init=epsg:4326"))
randomPointDestinations <- spTransform(randomPointDestinations, CRS("+init=epsg:4326"))
#Use dataframe, single row per origin-destination pair
randomPointOrigins <- data.frame(randomPointOrigins)
randomPointDestinations <- data.frame(randomPointDestinations)
#Distinguish x and y column names (for later CSV writing)
colnames(randomPointOrigins)[colnames(randomPointOrigins)=="x"] <- "origin_x"
colnames(randomPointOrigins)[colnames(randomPointOrigins)=="y"] <- "origin_y"
colnames(randomPointDestinations)[colnames(randomPointDestinations)=="x"] <- "dest_x"
colnames(randomPointDestinations)[colnames(randomPointDestinations)=="y"] <- "dest_y"
#Final set of origin-destination points
pointSet <- cbind(randomPointOrigins,randomPointDestinations)
#Create results matrix, one row per origin-destination pair
#Storing four results: distance and time of each route
#(Distance in metres, time in seconds)
#And also the strings for the address of origins and destinations
results <- matrix(nrow=pairNum , ncol=4)
#Iterate over required pair numbers, get data from google
for(i in 1:pairNum) {
#set google distance matrix query
#Google does y,x. Reverse order
#See https://developers.google.com/maps/documentation/distancematrix/ for option info
qry <- paste("origins=", pointSet[i,2] , "," , pointSet[i,1] ,
"&destinations=" ,pointSet[i,4] , "," , pointSet[i,3] ,
"&sensor=FALSE",
# "&mode=bicycling",
"&avoid=ferries",#not going to any islands!
sep=""#no spaces
)
#Get the JSON
gimme <- GET(
testURL,
query = qry,
#If using in Leeds University, obv: comment this out if not, or if using Leeds Uni wifi
#Use this to see details of proxy connection: c(use_proxy("www-cache.leeds.ac.uk:3128", 8080), verbose())
c(use_proxy("www-cache.leeds.ac.uk:3128", 8080))
)
#http://blog.rstudio.org/2014/03/21/httr-0-3/
stop_for_status(gimme)
store <- content(gimme)
#if result was OK, keep
# if(store$status=="OK") {
if(store$rows[[1]]$elements[[1]]$status=="OK") {
results[i,1] <- store$rows[[1]]$elements[[1]]$distance$value
results[i,2] <- store$rows[[1]]$elements[[1]]$duration$value
results[i,3] <- store$origin_addresses[[1]]
results[i,4] <- store$destination_addresses[[1]]
} else {
fail <- fail + 1
}
#pause between API calls. We're aiming for:
# "100 elements per 10 seconds."
# "2500 elements per 24 hour period."
#Two elements per call (origin and destination)
#Being conservative: 0.3 seconds should hit ~66 elements per 10 seconds
Sys.sleep(0.3)
print(paste("API call", i, "complete, status: ", store$rows[[1]]$elements[[1]]$status))
}#end for
#Append the coordinates used
readyForWriting <- cbind(data.frame(results),pointSet)
colnames(readyForWriting)[colnames(readyForWriting)=="X1"] <- "distance"
colnames(readyForWriting)[colnames(readyForWriting)=="X2"] <- "time"
colnames(readyForWriting)[colnames(readyForWriting)=="X3"] <- "origin"
colnames(readyForWriting)[colnames(readyForWriting)=="X4"] <- "destination"
#Strip out failed calls
readyForWriting <- readyForWriting[ !is.na(readyForWriting$distance) ,]
#Write the final results file, unique name each time
filename = paste("GoogleDistanceMatrixRandomPathRresults_",date(),".csv",sep="")
#spaces with underscores
filename <- gsub(" ", "_", filename)
#colons with underscores
filename <- gsub(":", "_", filename)
write.csv(readyForWriting, filename)
print(paste(pairNum, "attempts, ", (pairNum - fail), "successful."))
print(paste("File written: ", filename))