Skip to content

Instantly share code, notes, and snippets.

@fxi
Created June 25, 2015 12:29
Show Gist options
  • Save fxi/22518690f3834824c677 to your computer and use it in GitHub Desktop.
Save fxi/22518690f3834824c677 to your computer and use it in GitHub Desktop.
#'amReferralTable
#'@export
amReferralTable<-function(session=shiny:::getDefaultReactiveDomain(),inputSpeed,inputFriction,inputHf,inputHfTo,inputTblHf,inputTblHfTo,idField,idFieldTo,labelField,labelFieldTo,typeAnalysis,resol,dbCon, unitCost=c('s','m','h'),unitDist=c('m','km'),outReferral,outNearestDist,outNearestTime){
# check the clock
timeCheckAll<-system.time({
# set increment for the progress bar.
incN=0
inc=90/nrow(inputTblHf)
# set output table header label
hIdField <- paste0('from','__',amSubPunct(idField)) # amSubPunt to avoid unwanted char (accent, ponctuation..)
hLabelField <- paste0('from','__',amSubPunct(labelField))
hIdFieldTo <- paste0('to','__',amSubPunct(idFieldTo))
hLabelFieldTo <- paste0('to','__',amSubPunct(labelFieldTo))
hIdFieldNearest <- paste0('nearest','__',amSubPunct(idFieldTo))
hLabelFieldNearest <- paste0('nearest','__',amSubPunct(labelFieldTo))
hDistUnit <-paste0('distance','_',unitDist)
hTimeUnit <- paste0('time','_',unitCost)
# Create destination HF subset (To).
# NOTE: this has already be done outside for other functions.. but for coherence with origin HF (From) map, which need to be subseted in the loop, we also subset destination HF here.
qSqlTo<-paste("cat IN (",paste0(inputTblHfTo$cat,collapse=','),")")
execGRASS("v.extract",flags=c('overwrite'),input=inputHfTo,where=qSqlTo,output='tmp_ref_to')
# cost and dist from one to all selected in table 'to'
for(i in inputTblHf$cat){
timeCheck<-system.time({
incN=incN+1
qSqlFrom<-paste("cat==",i)
# create temporary origine facility map (from)
execGRASS("v.extract",flags=c('overwrite'),input=inputHf,where=qSqlFrom,output='tmp__ref_from')
# NOTE: only extract coordinate instead ? No.. we need points in network.
# create cumulative cost map for each hf : iso or aniso
switch(typeAnalysis,
'anisotropic'=amAnisotropicTravelTime(
inputSpeed=inputSpeed,
inputHf='tmp__ref_from',
inputStop='tmp_ref_to',
outputCumulative='tmp__cost',
outputDir='tmp__ref_dir',
returnPath=FALSE,
maxCost=0
),
'isotropic'=amIsotropicTravelTime(
inputFriction=inputFriction,
inputHf='tmp__ref_from',
inputStop='tmp_ref_to',
outputCumulative='tmp__cost',
outputDir='tmp__ref_dir',
maxCost=0
)
)
# extract time cost V1 = hf cat dest; V2 = time to reach hf
refTime=execGRASS(
'v.what.rast',
map='tmp_ref_to',
raster='tmp__cost',
flags='p',
intern=T
)%>%
gsub('\\*',NA,.) %>%
na.omit %>%
read.table(text=.,sep='|')
# rename grass output
names(refTime)<-c('tcat',hTimeUnit)
#unit transformation
if(!unitCost =='s'){
div<-switch(unitCost,
'm'=60,
'h'=3600,
'd'=86400
)
refTime[hTimeUnit]<-refTime[hTimeUnit]/div
}
refTime$cat=i
# extract network to compute distance
execGRASS('r.drain',
input='tmp__cost',
direction='tmp__ref_dir',
output='tmp__drain',
drain='tmp__drain',
flags=c('overwrite','c','d'),
start_points='tmp_ref_to'
)
# create new layer with start point as node
execGRASS('v.net',
input='tmp__drain',
points='tmp__ref_from',
output='tmp__net_from',
node_layer='2',
operation='connect',
threshold=resol-1,
flags='overwrite'
)
# create new layer with stop points as node
execGRASS('v.net',
input='tmp__net_from',
points='tmp_ref_to',
output='tmp__net_all',
node_layer='3',
operation='connect',
threshold=resol-1,
flags='overwrite'
)
# extrad distance for each end node.
execGRASS('v.net.distance',
input='tmp__net_all',
output='tmp__net_dist',
from_layer='3', # calc distance from all node in 3 to layer 2 (start point)
to_layer='2',
intern=T,
flags='overwrite'
)
# read attribute table of distance network.
refDist<-dbReadTable(dbCon,'tmp__net_dist')
# rename grass output
names(refDist)<-c('tcat','cat',hDistUnit)
# distance conversion
if(!unitDist=='m'){
div<-switch(unitDist,
'km'=1000
)
refDist[hDistUnit]<-refDist[hDistUnit]/div
}
# using data.table. TODO: convert previouse data.frame to data.table.
refTime<-as.data.table(refTime)
setkey(refTime,cat,tcat)
refDist<-as.data.table(refDist)
setkey(refDist,cat,tcat)
refTimeDist <- refDist[refTime]
#create or update table
if(incN==1){
ref=refTimeDist
}else{
ref<-rbind(ref,refTimeDist)
}
# remove tmp map
rmRastIfExists('tmp__*')
rmVectIfExists('tmp__*')
})
amUpdateProgressBar(session,'cumulative-progress',inc*incN)
print(timeCheck)
}
# set key to ref
setkey(ref,cat,tcat)
# Remove tmp map
rmVectIfExists('tmp_*')
# mergin from hf subset table and renaming.
valFrom<-inputTblHf[inputTblHf$cat %in% ref$cat, c('cat',idField,labelField)]
names(valFrom)<-c('cat',hIdField,hLabelField)
valFrom<-as.data.table(valFrom)
setkey(valFrom,cat)
valTo<-inputTblHfTo[inputTblHfTo$cat %in% ref$tcat,c('cat',idFieldTo,labelFieldTo)]
names(valTo)<-c('tcat',hIdFieldTo,hLabelFieldTo)
valTo<-as.data.table(valTo)
setkey(valTo,'tcat')
setkey(ref,cat)
ref<-ref[valFrom]
setkey(ref,tcat)
ref<-ref[valTo]
# set column subset and order
#refOut<-ref[,c(hIdField,hIdFieldTo,hDistUnit,hTimeUnit,hLabelField,hLabelFieldTo),with=F]
refOut<-ref[,c(
hIdField,
hLabelField,
hIdFieldTo,
hLabelFieldTo,
hDistUnit,
hTimeUnit
),with=F]
# set expression to evaluate nested query by group
expD<-parse(text=paste0(".SD[which.min(",hDistUnit,")]"))
expT<-parse(text=paste0(".SD[which.min(",hTimeUnit,")]"))
# Extract nearest feature by time and distance.
refNearestDist<-refOut[,eval(expD),by=hIdField]
refNearestTime<-refOut[,eval(expT),by=hIdField]
})
# Return meta data
meta<-list(
'Function'='amReferralTable',
'AccessMod revision'=amGetVersionLocal(),
'Date'=amSysTime(),
'Timing'=as.list(timeCheckAll)$elapsed,
'Iterations'=nrow(inputTblHf),
'Arguments'=list(
'input'=list(
'map'=list(
'cost'=list(
'speed'=inputSpeed,
'friction'=inputFriction
),
'facilities'=list(
'from'=inputHf,
'to'=inputHfTo
)
),
'table'=list(
'cat'=list(
'from'=inputTblHf$cat,
'to'=inputTblHfTo$cat
),
'names'=list(
'from'=names(inputTblHf),
'to'=names(inputTblHfTo)
)
)
),
'analysis'=typeAnalysis,
'unit'=list(
'distance'=unitDist,
'cost'=unitCost
),
'resol'=resol
),
'Output'=list(
outReferral,
outNearestDist,
outNearestTime
)
)
dbWriteTable(dbCon,outReferral,refOut,overwrite=T,row.names=F)
dbWriteTable(dbCon,outNearestDist,refNearestDist,overwrite=T,row.names=F)
dbWriteTable(dbCon,outNearestTime,refNearestTime,overwrite=T,row.names=F)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment