Distances routières avec R et l’API Mapquest
Voilà un petit bout de code que j’avais écrit pour obtenir rapidement la distance par la route entre deux lieux géographiques avec R. On utilise les librairies RCurl et XML pour interroger l’API Mapquest basée elle même sur les données d’OSM. Le code est constitué de trois fonctions :
- mapq.loc() renvoie un certain nombre d’infos sur un lieu (y compris ses coordonnées géographiques)
- mapq.dist() renvoie la distance entre deux points géographiques spécifiés par leurs coordonnées
- mapq.distance() : renvoie la distance routière entre deux points géographiques spécifiés par leurs noms. Choix de l’unité possible (« k » pour km ou « m » pour miles)
Une petite application de ces fonction est prévue pour le prochain billet 😉
On peut noter qu’une fonction équivalente est désormais fournie avec le package ggmap, basée elle sur le service Google Maps.
library (RCurl) library (XML) mapq.loc <- function(query, format="xml", limit=1, details=1) { urlroot <- "http://open.mapquestapi.com/nominatim/v1/search?" url <- paste(urlroot, "format=", format, "&q=", query, "&addressdetails=", details, "&limit=", limit, sep="") xmllocinfo <- getURL(url) xmllocinfo <- htmlParse(xmllocinfo) xmllocinfo <- xmlRoot(xmllocinfo) verif <- function(express) tryCatch(express, error=function(e) NULL) locinfo <- list() locinfo$lat <- verif(as.numeric(unlist(xpathApply(xmllocinfo, "/html/body/searchresults/place/@lat")))) locinfo$lon <- verif(as.numeric(unlist(xpathApply(xmllocinfo, "/html/body/searchresults/place/@lon")))) locinfo$city <- verif(as.character(xpathApply(xmllocinfo, "/html/body/searchresults/place/city", xmlValue))) locinfo$county <- verif(as.character(xpathApply(xmllocinfo, "/html/body/searchresults/place/county", xmlValue))) locinfo$state <- verif(as.character(xpathApply(xmllocinfo, "/html/body/searchresults/place/state", xmlValue))) locinfo$country <- verif(as.character(xpathApply(xmllocinfo, "/html/body/searchresults/place/country", xmlValue))) locinfo$countrycode <- verif(as.character(xpathApply(xmllocinfo, "/html/body/searchresults/place/country_code", xmlValue))) return(locinfo) } mapq.dist <- function(Alat, Alon, Blat, Blon, format="xml", unit="k") { urlroot <- "http://open.mapquestapi.com/directions/v0/route?" url <- paste(urlroot, "outFormat=", format, "&unit=", unit, "&from=", Alat, ",", Alon, "&to=", Blat, ",", Blon, sep="") xmldistinfo <- getURL(url) xmldistinfo <- htmlParse(xmldistinfo) xmldistinfo <- xmlRoot(xmldistinfo) verif <- function(express) tryCatch(express, error=function(e) NULL) distance <- verif(as.numeric(xpathApply(xmldistinfo, "/html/body/response/route/distance", xmlValue))) return(distance) } mapq.distance <- function(from, to, unit="k", print=TRUE) { from.f <- chartr(" ","+", from) to.f <- chartr(" ","+", to) from.info <- mapq.loc(from.f) to.info <- mapq.loc(to.f) distance <- mapq.dist(from.info$lat, from.info$lon, to.info$lat, to.info$lon, unit=unit) if(unit=="k") unit.print <- "Km" if(unit=="m") unit.print <- "Miles" if (print==TRUE){ cat("Distance between", "\n") cat(from, ",", from.info$state, ",", toupper(from.info$countrycode), "and", to, ",", to.info$state, ",", toupper(to.info$countrycode), "\n") cat(distance, unit.print, "\n") } else { invisible(distance) } }