1 ```#' HERE Routing API: Calculate Isoline ``` 2 ```#' ``` 3 ```#' Calcuates isolines (\code{POLYGON} or \code{MULTIPOLYGON}) using the HERE 'Routing' API ``` 4 ```#' that connect the end points of all routes leaving from defined centers (POIs) with either ``` 5 ```#' a specified length, a specified travel time or consumption. ``` 6 ```#' ``` 7 ```#' @references ``` 8 ```#' \href{https://developer.here.com/documentation/routing/topics/resource-calculate-isoline.html}{HERE Routing API: Calculate Isoline} ``` 9 ```#' ``` 10 ```#' @param poi \code{sf} object, Points of Interest (POIs) of geometry type \code{POINT}. ``` 11 ```#' @param datetime \code{POSIXct} object, datetime for the departure (or arrival if \code{arrival = TRUE}). ``` 12 ```#' @param arrival boolean, are the provided Points of Interest (POIs) the origin or destination locations (\code{default = FALSE})? ``` 13 ```#' @param range numeric, a vector of type \code{integer} containing the breaks for the generation of the isolines: (1) time in seconds; (2) distance in meters; (3) consumption in costfactor. ``` 14 ```#' @param range_type character, unit of the isolines: \code{"distance"}, \code{"time"} or \code{"consumption"}. ``` 15 ```#' @param type character, set the routing type: \code{"fastest"} or \code{"shortest"}. ``` 16 ```#' @param mode character, set the transport mode: \code{"car"}, \code{"pedestrian"} or \code{"truck"}. ``` 17 ```#' @param traffic boolean, use real-time traffic or prediction in routing (\code{default = FALSE})? If no \code{datetime} is set, the current timestamp at the moment of the request is used for \code{datetime}. ``` 18 ```#' @param aggregate boolean, aggregate (with function \code{min}) and intersect the isolines from geometry type \code{POLYGON} to geometry type \code{MULTIPOLYGON} (\code{default = TRUE})? ``` 19 ```#' @param url_only boolean, only return the generated URLs (\code{default = FALSE})? ``` 20 ```#' ``` 21 ```#' @return ``` 22 ```#' An \code{sf} object containing the requested isolines. ``` 23 ```#' @export ``` 24 ```#' ``` 25 ```#' @examples ``` 26 ```#' # Provide an API Key for a HERE project ``` 27 ```#' set_key("") ``` 28 ```#' ``` 29 ```#' # Isochrone for 5, 10, 15, 20, 25 and 30 minutes driving time ``` 30 ```#' isolines <- isoline( ``` 31 ```#' poi = poi, ``` 32 ```#' range = seq(5, 30, 5) * 60, ``` 33 ```#' url_only = TRUE ``` 34 ```#' ) ``` 35 ```isoline <- function(poi, datetime = Sys.time(), arrival = FALSE, ``` 36 ``` range = seq(5, 30, 5) * 60, range_type = "time", ``` 37 ``` type = "fastest", mode = "car", traffic = FALSE, ``` 38 ``` aggregate = TRUE, url_only = FALSE) { ``` 39 40 ``` # Checks ``` 41 1 ``` .check_points(poi) ``` 42 1 ``` .check_datetime(datetime) ``` 43 1 ``` .check_range_type(range_type) ``` 44 1 ``` .check_type(type = type, request = "calculateisoline") ``` 45 1 ``` .check_mode(mode = mode, request = "calculateisoline") ``` 46 1 ``` .check_boolean(traffic) ``` 47 1 ``` .check_boolean(arrival) ``` 48 1 ``` .check_boolean(aggregate) ``` 49 1 ``` .check_boolean(url_only) ``` 50 51 ``` # Add API key ``` 52 1 ``` url <- .add_key( ``` 53 1 ``` url = "https://isoline.route.ls.hereapi.com/routing/7.2/calculateisoline.json?" ``` 54 ``` ) ``` 55 56 ``` # Add point coords ``` 57 1 ``` poi <- sf::st_coordinates( ``` 58 1 ``` sf::st_transform(poi, 4326) ``` 59 ``` ) ``` 60 1 ``` poi <- paste0( ``` 61 1 ``` "geo!", poi[, 2], ",", poi[, 1] ``` 62 ``` ) ``` 63 1 ``` url = paste0( ``` 64 1 ``` url, ``` 65 0 ``` if (!arrival) {"&start="} else {"&destination="}, ``` 66 1 ``` poi ``` 67 ``` ) ``` 68 69 ``` # Add range and range type ``` 70 1 ``` url = paste0( ``` 71 1 ``` url, ``` 72 1 ``` "&range=", ``` 73 1 ``` paste0(range, collapse = ","), ``` 74 1 ``` "&rangetype=", ``` 75 1 ``` range_type ``` 76 ``` ) ``` 77 78 ``` # Add consumption details ``` 79 1 ``` if (range_type == "consumption") { ``` 80 0 ``` url <- paste0( ``` 81 0 ``` url, ``` 82 0 ``` "&consumptionmodel=", ``` 83 0 ``` "standard", ``` 84 0 ``` "&customconsumptiondetails=", ``` 85 0 ``` "speed,0,1.7,10,1.4,30,1.1,50,1.0,70,1.1,100,1.2,120,1.4,140,1.8;ascent,30.0;descent,10.0" ``` 86 ``` ) ``` 87 ``` } ``` 88 ``` # Add mode ``` 89 1 ``` url <- .add_mode( ``` 90 1 ``` url = url, ``` 91 1 ``` type = type, ``` 92 1 ``` mode = mode, ``` 93 1 ``` traffic = traffic ``` 94 ``` ) ``` 95 96 ``` # Add departure time ``` 97 1 ``` url <- .add_datetime( ``` 98 1 ``` url, ``` 99 1 ``` datetime, ``` 100 1 ``` if (arrival) "arrival" else "departure" ``` 101 ``` ) ``` 102 103 ``` # Return urls if chosen ``` 104 0 ``` if (url_only) return(url) ``` 105 106 ``` # Request and get content ``` 107 1 ``` data <- .get_content( ``` 108 1 ``` url = url ``` 109 ``` ) ``` 110 0 ``` if (length(data) == 0) return(NULL) ``` 111 112 ``` # Extract information ``` 113 1 ``` ids <- .get_ids(data) ``` 114 1 ``` count <- 0 ``` 115 1 ``` isolines <- sf::st_as_sf( ``` 116 1 ``` as.data.frame(data.table::rbindlist( ``` 117 1 ``` lapply(data, function(con) { ``` 118 1 ``` count <<- count + 1 ``` 119 1 ``` df <- jsonlite::fromJSON(con) ``` 120 1 ``` geometry <- lapply(df\$response\$isoline\$component, function(iso){ ``` 121 1 ``` .polygon_from_pointList(iso\$shape[[1]]) ``` 122 ``` }) ``` 123 1 ``` sf::st_as_sf( ``` 124 1 ``` data.table::data.table( ``` 125 1 ``` id = ids[count], ``` 126 1 ``` departure = if(arrival) (datetime - df\$response\$isoline\$range) else datetime, ``` 127 1 ``` arrival = if(arrival) datetime else (datetime + df\$response\$isoline\$range), ``` 128 1 ``` range = df\$response\$isoline\$range, ``` 129 1 ``` lng = df\$response\$center\$longitude, ``` 130 1 ``` lat = df\$response\$center\$latitude ``` 131 ``` ), ``` 132 1 ``` geometry = sf::st_as_sfc(geometry, crs = 4326) ``` 133 ``` ) ``` 134 ``` }) ``` 135 1 ``` )), check_ring_dir = TRUE ``` 136 ``` ) ``` 137 138 ``` # Aggregate ``` 139 1 ``` if (aggregate) { ``` 140 1 ``` tz <- attr(isolines\$departure, "tzone") ``` 141 1 ``` isolines <- sf::st_set_precision(isolines, 1e5) ``` 142 1 ``` isolines <- sf::st_make_valid(isolines) ``` 143 1 ``` isolines <- stats::aggregate(isolines, by = list(isolines\$range), ``` 144 1 ``` FUN = min, do_union = TRUE, simplify = TRUE, ``` 145 1 ``` join = sf::st_intersects) ``` 146 1 ``` isolines <- sf::st_make_valid(isolines) ``` 147 1 ``` suppressMessages( ``` 148 1 ``` isolines <- sf::st_difference(isolines) ``` 149 ``` ) ``` 150 1 ``` isolines\$Group.1 <- NULL ``` 151 1 ``` isolines\$id <- NA ``` 152 1 ``` attr(isolines\$departure, "tzone") <- tz ``` 153 1 ``` attr(isolines\$arrival, "tzone") <- tz ``` 154 155 ``` # Fix geometry collections ``` 156 1 ``` suppressWarnings( ``` 157 1 ``` isolines <- sf::st_collection_extract( ``` 158 1 ``` isolines, type = c("POLYGON") ``` 159 ``` ) ``` 160 ``` ) ``` 161 ``` } ``` 162 163 1 ``` rownames(isolines) <- NULL ``` 164 1 ``` return(isolines) ``` 165 ```} ```

Read our documentation on viewing source code .