Interpolate position 5 minutes after starting from point A to B - r

below is an example of finding route, travel time and travel distance from 'One World Trade Center, NYC' to 'Madison Square Park, NYC' using osrm package in R. (I learnt it from Road Routing in R). The travel time here is 10.37 minutes.
Q. How can I interpolate and find location after 5 minutes.
library(sf)
library(dplyr)
library(tidygeocoder)
library(osrm)
# 1. One World Trade Center, NYC
# 2. Madison Square Park, NYC
adresses <- c("285 Fulton St, New York, NY 10007",
"11 Madison Ave, New York, NY 10010")
# geocode the two addresses & transform to {sf} data structure
data <- tidygeocoder::geo(adresses, method = "osm") %>%
st_as_sf(coords = c("long", "lat"), crs = 4326)
osroute <- osrm::osrmRoute(loc = data,
returnclass = "sf")
summary(osroute)
library(leaflet)
leaflet(data = data) %>%
addProviderTiles("CartoDB.Positron") %>%
addMarkers(label = ~address) %>%
addPolylines(data = osroute,
label = "OSRM engine",
color = "red")

Use the osrm::osrmIsochrone() function to find the five minute travel distance polygon, and then find the point that the route intersects the polygon.
It looks like its on Clarkson Street between Hudson & Varick.
library(sf)
library(dplyr)
library(tidygeocoder)
library(osrm)
# 1. One World Trade Center, NYC
# 2. Madison Square Park, NYC
adresses <- c("285 Fulton St, New York, NY 10007",
"11 Madison Ave, New York, NY 10010")
# geocode the two addresses & transform to {sf} data structure
data <- tidygeocoder::geo(adresses, method = "osm") %>%
st_as_sf(coords = c("long", "lat"), crs = 4326)
# get route from 285 fulton to 11 madison
osroute <- osrmRoute(src = data[1,], dst = data[2,], returnclass = 'sf')
# five minute isochrone from 285 fulton
five_min_isochrone <- osrmIsochrone(data[1,], breaks = 5, returnclass = 'sf')
# isochrone has to be cast to MULTILINESTRING to find intersection as a point
intersection <- five_min_isochrone %>%
st_cast('MULTILINESTRING') %>%
st_intersection(osroute)
library(leaflet)
leaflet(data = data) %>%
addProviderTiles("CartoDB.Positron") %>%
addMarkers(label = ~address) %>%
addPolylines(data = osroute,
label = "OSRM engine",
color = "red") %>%
addPolygons(data = five_min_isochrone) %>%
addMarkers(data = intersection,
label = '5 minute distance')

Related

Searching a Leaflet Map?

I started working with a shapefile in R. In this shapefile, each "boundary" is uniquely defined by a value in "col1" (e.g. ABC111, ABC112 , ABC113, etc.):
library(sf)
library(igraph)
sf <- sf::st_read("C:/Users/me/OneDrive/Documents/shape5/myshp.shp", options = "ENCODING=WINDOWS-1252")
head(sf)
Simple feature collection with 6 features and 3 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 7201955 ymin: 927899.4 xmax: 7484015 ymax: 1191414
Projected CRS: PCS_Lambert_Conformal_Conic
col1 col2 col3 geometry
620 ABC111 99 Region1 MULTIPOLYGON (((7473971 119...
621 ABC112 99 Region1 MULTIPOLYGON (((7480277 118...
622 ABC113 99 Region1 MULTIPOLYGON (((7477124 118...
627 ABC114 99 Region1 MULTIPOLYGON (((7471697 118...
638 ABC115 99 Region1 MULTIPOLYGON (((7209908 928...
639 ABC116 99 Region1 MULTIPOLYGON (((7206683 937...
> dim(sf)
[1] 500 4
sf_trans = st_transform(sf, 4326)
I then plotted this data using the leaflet library:
library(leaflet)
map = leaflet(sf_trans) %>% addPolygons( stroke = FALSE) %>% addTiles(group = "OSM") %>% addProviderTiles("CartoDB.DarkMatter", group = "Carto") %>% addPolygons(data = st_trans, weight=5, col = 'blue')
What I want to do is to try and make a "searchable" map. For example, imagine that "ABC111" is like an American ZIP Code. I want to make a map in which you can search for "ABC111" and the geographical outline of "ABC111" will be highlighted.
As an example, the ZIP Code of the Space Needle Tower in Seattle, Washington (USA) is "98109". If I search for this ZIP Code on Google Maps, the outline of this ZIP code is highlighted in red:
I was able to find a question on stackoverflow that explains how to add a search bar on a leaflet map for individual points (R leaflet search marker NOT work):
libary(dplyr)
library(leaflet)
library(leaflet.extras)
# using the same reproducible data from the question/example
cities <- read.csv(
textConnection("City,Lat,Long,Pop
Boston,42.3601,-71.0589,645966
Hartford,41.7627,-72.6743,125017
New York City,40.7127,-74.0059,8406000
Philadelphia,39.9500,-75.1667,1553000
Pittsburgh,40.4397,-79.9764,305841
Providence,41.8236,-71.4222,177994
"))
leaflet(cities) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addResetMapButton() %>%
# these markers will be "invisible" on the map:
addMarkers(
data = cities, lng = ~Long, lat = ~Lat, label = cities$City,
group = 'cities', # this is the group to use in addSearchFeatures()
# make custom icon that is so small you can't see it:
icon = makeIcon(
iconUrl = "http://leafletjs.com/examples/custom-icons/leaf-green.png",
iconWidth = 1, iconHeight = 1
)
) %>%
addSearchFeatures(
targetGroups = 'cities', # group should match addMarkers() group
options = searchFeaturesOptions(
zoom=12, openPopup = TRUE, firstTipSubmit = TRUE,
autoCollapse = TRUE, hideMarkerOnCollapse = TRUE
)
)
But is there a way that the above code can be modified such that when you enter a term in the search bar (e.g. ABC111, ABC112), the entire boundaries of this region are highlighted in red?
Thank you!

Unable to find the distance between the centroid of a census tract and school location coordinates

library(tidyverse)
library(tidycensus)
library(sf)
library(sp)
#install.packages('geosphere')
library('geosphere')
library(rgeos)
library(sfheaders)
#install.packages('reshape')
library('reshape')
#> Linking to GEOS 3.6.1, GDAL 2.1.3, PROJ 4.9.3
census_tract <- get_acs(geography = "tract",
variables = "B19013_001",
state = "CA",
county = c("San Joaquin","Merced","stanislaus"),
geometry = TRUE,
year = 2020)
plot(st_geometry(census_tract), axes = T)
plot(st_centroid(st_geometry(census_tract)), pch = "+", col = "red", add = T)
library(ggplot2)
ggplot(census_tract) + geom_sf() +
geom_sf(aes(geometry = st_centroid(st_geometry(census_tract))), colour = "red")
census_tract$centroid <- st_centroid(st_geometry(census_tract))
schoolloc <- read.csv("C:/Users/rlnu/Desktop/EXAMPLE/pubschls.csv")
schoolloc <- schoolloc%>% filter(County == c("San Joaquin","Merced","Stanislaus"))
census_tract <- census_tract %>%
mutate(long = unlist(map(census_tract$centroid,1)),
lat = unlist(map(census_tract$centroid,2)))
shortest_distance$min_distance <- expand.grid.df(census_tract,schoolloc) %>%
mutate(distance = distHaversine(p1 = cbind(long,lat),
p2 = cbind(Longitude,Latitude))
`
I am trying to find distance between the each census tract's centroid to three nearest schools. please help me out with it. I have written some code . The logic is wrong and the code is not working
Can achieve this using the sf package.
I could not access you schools data so made a dummy set of 4 schools.
library(sf)
schools <- data.frame(School_Name=c("School_1", "School_2", "School_3", "School_4"), Lat=c(37.83405, 38.10867, 37.97743, 37.51615), Long=c(-121.2810, -121.2312, -121.2575, -120.8772)) %>% st_as_sf(coords=c("Long", "Lat"), crs=4326)
Convert tracts to centroids and make the crs the same as the school set then calculate the distance matrix
census_centroid <- st_centroid(census_tract) %>% st_transform(4326)
DISTS<- st_distance(census_centroid, schools)
Rename the columns to be the school IDs
colnames(DISTS) <- schools$School_Name
link it back to centoids
cent_dists <- cbind(census_centroid, DISTS) %>% #bind ditances to centroids
pivot_longer(cols = -names(census_centroid), names_to = "School Name", values_to = "Distance") %>% #make long for ordering
group_by(NAME) %>% #group by centroid
slice_min(Distance,n= 3) %>% # take three closest
mutate(Near_No=paste0("Near_School_",rep(1:3))) #School distance ranking
Make wide if one row per census centroid desired, might want to play with column order though
cent_dists_wide <- cent_dists %>%
pivot_wider(names_from = c("Near_No"), values_from = c("Distance", "School Name"), names_sort = FALSE) #make wid if wyou want one row per centoid

Plotting a chloropleth map of Australian states

I plotted a dot density map of the Australian states and am now trying to plot a chloropleth map of the Australian states using the leaflet package and color each state by the count value. I have the following data frame
state count latitude longitude
Australian Capital Territory 125 ... ...
New South Wales 45
Northern Territory 75
Queensland 12
South Australia 245
Tasmania 4895
Victoria 279
The following is the code I used to plot the dot density map
leaflet(aus_state_counts) %>%
addTiles() %>%
addCircleMarkers(
layerId = ~state,
label = ~state,
radius = ~count
) %>%
fitBounds(lng1 = max(aus_state_counts$longitude) ,lat1 = max(aus_state_counts$latitude),
lng2 = min(aus_state_counts$longitude) ,lat2 = min(aus_state_counts$latitude)
)
I am unsure how to plot the states on the map? Do I need additional information for this?
For a choropleth map you will need some spatial polygon data in the form of a shape file (.shp) or GeoJSON (.geojson). Below should work.
library(sf)
library(leaflet)
library(dplyr)
# GeoJSON Data
states <- read_sf("https://raw.githubusercontent.com/rowanhogan/australian-states/master/states.geojson")
counts <- data.frame(state=c("Australian Capital Territory", "New South Wales", "Northern Territory", "Queensland",
"South Australia", "Tasmania", "Victoria"), count=c(125,45,75,12,245,4895,279))
# Join to count data
data <- states %>%
dplyr::left_join(counts, by=c("STATE_NAME" = "state"))
# Specify choropleth colors
pal <- colorQuantile("Blues", domain = data$count)
# Plot Map
leaflet(data) %>%
addTiles() %>%
addPolygons(fillColor=~pal(count), fillOpacity=0.8, color="white", weight=1)

Leaflet setview() to look at County Map

Hello all experts out there,
I am very new to R and leaflet
I would like to create a shiny dashboard and within it, I want to create a map with leaflet. Here is how I want it to be, first, the user will pick a state, then, you may or may not pick a county. So if they pick a state I would like to use setview() to just look at the chosen state, and if they pick a state and a county, then setview() to look at the chosen county.
So first I want to make sure my leaflet code works first, before I embed it into shiny server. So I ran the following code assuming that the user picks California state and county Los Angeles.
I got the following error and not sure how to fix it.
Any suggestion? Thank you so much in advance!
Error in cut.default(x, binsToUse, labels = FALSE, include.lowest = TRUE, :
'breaks' are not unique
> head(lonlat)
STATE COUNTY county.State lon lat
1 AK KENAI PENINSULA KENAI PENINSULA,AK -151.3044 60.58293
2 AK ANCHORAGE ANCHORAGE,AK -149.8557 61.22002
3 AK DENALI DENALI,AK -145.8662 63.04024
4 AK BETHEL BETHEL,AK -161.7558 60.79222
5 AK MATANUSKA-SUSITNA MATANUSKA-SUSITNA,AK -150.5125 61.54361
6 AK KODIAK ISLAND KODIAK ISLAND,AK -152.3539 57.80459
>
states <- readOGR("cb_2015_us_state_20m.shp",
layer = "cb_2015_us_state_20m", GDAL1_integer64_policy = TRUE)
states <- subset(states, states$STUSPS %in% c("CA"))
class(states)
leaflet(data = map_dat[map_dat$STATE %in% "CA" &
map_dat$COUNTY %in% "LOS ANGELES",]) %>%
addProviderTiles(
providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)
) %>%
addPolygons(data=states,color = "#444444", weight = 1, smoothFactor = 0.5,
opacity = 1.0, fillOpacity = 0.5,
fillColor = ~colorQuantile("YlOrRd", ALAND)(ALAND),
highlightOptions = highlightOptions(color = "white", weight = 2,
bringToFront = TRUE))
selectedCounty <- lonlat[lonlat$COUNTY == "LOS ANGELES" &&
lonlat$STATE == "CA", ]
#leafletProxy(mapId = "allmap") %>%
setView(lng = selectedCounty$lon, lat = selectedCounty$lat, zoom = 5)

Layering polygons and location points in r

Oklahoma recently legalized medical marijuana, and I'm making a map of where dispensaries can set up. That depends on two things: it has to be in the right zoning area, and can't be too close to a school, church, or playground. I have two maps that show those things, but can't figure out how to layer them together. What I'm trying to achieve is showing how much of the correct zoning area is off-limits because it's too close to a school, church, etc.
The zoning code:
zoning_shapes <- "Primary_Zoning.shp"
zoning <- st_read(zoning_shapes)
library(dplyr)
zoning_1 <- filter(zoning, P_ZONE!="R-1")
zoning_2 <- filter(zoning_1, P_ZONE!="SPUD")
zoning_3 <- filter(zoning_2, P_ZONE!="AA")
zoning_4 <- filter(zoning_3, P_ZONE!="R-2")
zoning_5 <- filter(zoning_4, P_ZONE!="R-4")
zoning_6 <- filter(zoning_5, P_ZONE!="PUD")
zoning_7 <- filter(zoning_6, P_ZONE!="I-3")
zoning_8 <- filter(zoning_7, P_ZONE!="R-A")
zoning_9 <- filter(zoning_8, P_ZONE!="O-1")
zoning_10 <- filter(zoning_9, P_ZONE!="R-3")
zoning_11 <- filter(zoning_10, P_ZONE!="R-A2")
zoning_12 <- filter(zoning_11, P_ZONE!="R-1ZL")
zoning_13 <- filter(zoning_12, P_ZONE!="R-3M")
zoning_14 <- filter(zoning_13, P_ZONE!="R-4M")
zoning_15 <- filter(zoning_14, P_ZONE!="R-MH-1")
zoning_16 <- filter(zoning_15, P_ZONE!="R-MH-2")
zoning_17 <- filter(zoning_16, P_ZONE!="C-HC")
zoning_18 <- filter(zoning_17, P_ZONE!="HP")
zoning_19 <- filter(zoning_18, P_ZONE!="NC")
zoning_20 <- filter(zoning_19, P_ZONE!="AE-1")
zoning_21 <- filter(zoning_20, P_ZONE!="AE-2")
library(ggplot2)
library(sf)
ggplot(zoning_21) + geom_sf() +
theme_void() +
theme(panel.grid.major =
element_line(colour = 'transparent'))
The prohibited-location code:
library(dplyr)
library(tigris)
library(sf)
library(ggplot2)
library(leaflet)
library(readr)
locations <- read_csv("Marijuana_map_CSV.csv")
View(locations)
mew <- colorFactor(c("red", "blue", "purple"), domain=c("School", "Church", "Playground"))
okc_locations <- leaflet(locations) %>%
addTiles() %>%
setView(-97.5164, 35.4676, zoom = 7) %>%
addCircles(~Longitude, ~Latitude, popup=locations$Name,
weight = 3, radius=304.8,
color=~mew(locations$Type), stroke = T,
fillOpacity = 0.8) %>%
addPolygons(data=zoning_21, fillColor = "limegreen",
fillOpacity = 0.5, weight = 0.2,
smoothFactor = 0.2)
okc_locations
The problem I'm running into is that when I try to add the okc_locations code to the zoning_21 code, I get one red dot that's far away and a very compressed version of the city's zoning. When I try adding the zoning polygons to the to the prohibited-points map, they don't show up.
Any ideas of how to get these two maps to play together? Thank you!
Based on our conversation in the comments, it seems that you are having an issue with different projections, in which case you will want to use st_transform (documented here)
First, I made up some fake data:
locations <-
data.frame(Name = c("St. Josephs", "St. Anthony", "Edwards Elementary"),
type = c("Church", "Playground", "School"),
long = c(35.4722725, 35.4751038, 35.4797194),
lat = c(-97.5202865,-97.5239513,-97.4691759))
I downloaded tiger shapefiles for all counties, then narrowed to Oklahoma County:
us_counties <- read_sf("cb_2017_us_county_500k.shp")
ok_county <- subset(us_counties, STATEFP == "40" & NAME == "Oklahoma")
> print(st_crs(ok_county))
Coordinate Reference System:
EPSG: 4269
proj4string: "+proj=longlat +datum=NAD83 +no_defs"
So I then used st_transform:
t2 <- st_transform(ok_county, "+proj=longlat +datum=WGS84")
> print(st_crs(t2))
Coordinate Reference System:
EPSG: 4326
proj4string: "+proj=longlat +datum=WGS84 +no_defs"
And loading it into leaflet as so:
leaflet(locations) %>%
addTiles() %>%
setView(-97.5164, 35.4676, zoom = 11) %>%
addMarkers(~lat, ~long, popup=locations$Name) %>%
addPolygons(data=t2, fillColor = "limegreen",
fillOpacity = 0.5, weight = 0.2,
smoothFactor = 0.2)
Yields this map:

Resources