Custom map style with ggmap - r

I have customized a style for use with ggmap using https://mapstyle.withgoogle.com/. My question is how to integrate the JSON into my R code.
I tried the following code to no avail:
map <- get_googlemap(center = 'London', zoom = 15,
style = c('element:labels|visibility:off', 'feature:road.local|visibility:off'))
ggmap(map)
It works with either of the style commands alone but not together. Where is the bug in my code?

I have developed a package ggmapstyles, which should help with this problem: https://github.com/dr-harper/ggmapstyles
The package lets you select designs from Snazzy Maps, and using the style from the page is as simple as copying the URL into the style:
devtools::install_github("mikey-harper/ggmapstyles")
library(ggmapstyles)
map <- get_snazzymap(center = 'London',
mapRef = "https://snazzymaps.com/style/61/blue-essence")
ggmap(map)
If you don't find a design you like, you can join Snazzy Maps for free and make your own custom design within the web browser.

I'm unclear myself on how exactly ggmap expects to receive styling, but get_googlemap has a parameter to inject a string into the URL sent to the Google Maps API. Based on the Google Maps docs, your strings seem formatted correctly for injecting. You can collapse each of those style specifications into a single string, and give that to the inject parameter rather than the style one.
So
stylestr <- sprintf("&style=%s", c("element:labels|visibility:off", "feature:road.local|visibility:off") %>% paste(collapse = "")
will yield the string &style=element:labels|visibility:off&style=feature:road.local|visibility:off
that can be used as your inject parameter. (I used sprintf and paste to make it easy for adding a whole slew of style specs.)

Related

Extracting image from web using Rvest

I'm trying to use R to extract player photos from the PGA website. The following is my attempt at getting the image URLs, but it does not show the images or the image is blank as shown in the image below.
if(!require(pacman))install.packages("pacman")
pacman::p_load('rvest', 'stringi', 'dplyr', 'tidyr', 'measurements', 'reshape2','foreach','doParallel','curl','httr','Iso','stringi','janitor')
PGA_url <- "https://www.pgatour.com"
pga_web=read_html(paste0(PGA_url,'/players.html'))
plyers_photo <- pga_web%>%html_nodes("[class='player-card']")%>%html_nodes('div.player-image-wrapper')%>%html_nodes('img')%>%html_attr('src')
Could someone kindly tell me what I'm doing wrong?
If you examine the page source you will see that you are retrieving the content as per the page source i.e. where there is a default img value. Scan across and you may notice that there is a data-src attribute adjacent which has an alternate ending for the png of the form matching regex: headshots_\d{5}\.png.
When JavaScript runs in the browser, which doesn't happen with an xmlhttp request through rvest, those urls are dynamically updated with the default png endings replaced with those in the data-src attributes.
Either replace the endings you are getting with that attribute's value, for the set-size small image, or instead, use the part up to and including upload as a base, and combine that with the extracted data-src values to give large images.
There is also no need for all those chained html_nodes() calls. A single call with an appropriate css selector list will do. Also, prefer the maintained html_elements() method, over the old html_nodes():
library(rvest)
library(magrittr)
PGA_url <- "https://www.pgatour.com"
pga_web <- read_html(paste0(PGA_url, "/players.html"))
placeholder_link <- 'https://pga-tour-res.cloudinary.com/image/upload/'
plyers_photo <- pga_web %>%
html_elements(".player-card .player-image-wrapper img") %>%
html_attr("data-src") %>% paste0(placeholder_link, .)

How can I extract various tables from Wikipedia using R?

I have the next link:
https://en.wikipedia.org/wiki/List_of_prime_ministers_of_Spain
I'm trying to extract the information about Prime Ministers but it gives a table of data without any apparent order.
This is currently the code that I am using
library(XML)
library(httr)
url = "https://en.wikipedia.org/wiki/List_of_prime_ministers_of_Spain"
url <- GET(url)
datos = readHTMLTable(rawToChar(url$content), header=T,stringsAsFactors=F)
tabla2= datos[[2]]
I would suggest using Selenium. Through Selenium API you can access all functionalities of the DOM.Prior I have used urlib library in Python but it didn't help if the page uses a lot of functionality thus the DOM always changes.

How to add ArcGIS server layer using leaflet.esri package?

I am trying to add a layer from a published ArcGIS service feature into a leaflet map in R using the leaflet.esri package.
I've read the documentations here https://rdrr.io/cran/leaflet.esri/man/addEsriTiledMapLayer.html and here https://cran.r-project.org/web/packages/leaflet.esri/leaflet.esri.pdf and have tested the examples
My code looks like this:
library(leaflet)
library(leaflet.esri)
leaflet() %>% setView(lng = 55.0876632, lat = 25.0755935, zoom = 10) %>%
addEsriTiledMapLayer(
url = "https://smart.gis.gov.ae/dmgis104/rest/services/Misc/Env_Imagery/MapServer")
Update: Note that no username or password is required.
I've confirmed that url works by adding it as an ArcGIS server in ArcCatalog, but when I try to run the above in R I just get a blank leaflet map.
How do I specify which layer from the above url to load? There are a number of layers available at that url, such as "Misc/IMAGE2018" and I would like to load these into leaflet.
I am a bit confused as well because when I inspect the url in ArcCatlog it shortens it to "Server URL: https://smart.gis.gov.ae/dmgis104/services" instead of the above, but I am not sure if that matters. See screen shot below as example of ArcCatlog.
Thanks in advance
the issue is that your map service doesn't use the typical web mercator projection and tiling scheme.
you can find an example which includes extra code to explicitly define a custom projection here: http://esri.github.io/esri-leaflet/examples/non-mercator-projection.html

How to modify the DataLabel fill (using a solid fill color)?

I'm trying to edit the data labels for a chart I'm writing on the slide. I can access the text of the datalabel using the methods available but as of yet the datalabel.fill is not existent. Any workarounds welcome if this is not planned on being added to the library in the future.
I've already gone through the source code in the github (https://github.com/scanny/python-pptx) but the datalabel class only has the font, has_text_frame, position, text_frame, _dLbl, _get_or_add_dLbl, _get_or_add_rich, _get_or_add_tx_rich, _get_or_add_txPr, and _remove_tx_rich methods. No fill or line fill methods is available.
The script I'm running does something similar for cells in a table:
cell.fill.solid()
cell.fill.fore_color.rgb = color_list[((col>0)*1)][i%2]
I'm looking at replicating the functionality on datalabels for chart series, with code that looks like this:
label.fill.solid()
label.fill.rgb = RGBColor(0x9B,0xBB,0x59)
label.fill.alpha = Alpha(.2)
label.line.fill.solid()
label.line.rgb = RGBColor(0xF0,0xF0,0x00)
The expected output xml should put the following for data labels:
<c:spPr>
<a:solidFill>
<a:srgbClr val="9BBB59">
<a:alpha val="80000"/>
</a:srgbClr>
</a:solidFill>
<a:ln>
<a:solidFill>
<a:schemeClr val="F0F000"/>
</a:solidFill>
</a:ln>
</c:spPr>
Actual output is non-existent as there is no method to do this directly.
This feature is not yet implemented, but if it was implemented it would be a .format property on the DataLabel object.
Typically users will work around an API gap like this by adding what we typically call a "workaround function" to the client code that manipulates the underlying XML directly, in this case, to add an <c:spPr> subtree in the right place.
python-pptx can generally get you close as far as a parent element is concerned. In this case, it can get you to the <c:dLbl> element like this:
data_label = chart.series[0].points[0].data_label
dLbl = data_label._dLbl
print(dLbl.xml)
The leading underscore in ._dLbl is your hint that you're getting into internals and if things don't go well it's something you're doing wrong, not an issue to be reported.
The dLbl object is an lxml.etree._Element object and can be manipulated with that API. If you have a search on "python-pptx workaround function" you'll find some examples for how to create new elements and put them where you want them.
The .xml property available on any python-pptx XML element object is handy for inspecting the results along the way. opc-diag can also be handy for inspecting PPTX files generated by PowerPoint or python-pptx for analysis or diagnostic purposes.

Using a plugin to call Google Maps API from within Leaflet in R

I am new here and wanted help to figure out how to call a Google Maps base layer using the Google Maps API in a Leaflet map in R. Here's what I have learnt till now:
Pavel Shramov's Leaflet plugins allow Google's base maps to be called from inside Leaflet JS, in a manner that is, from what I understand, compliant with Google's ToS. An example of this is available here, which works quite well.
There are general instructions on using arbitrary Leaflet JS plugins in Leaflet for R via htmltools and htmlwidgets.
Based on the above, I understand that my code in R will need to look somewhat as follows, but I can't get a Google basemap to load:
library(leaflet)
library(htmltools)
library(htmlwidgets)
# 1: Tell htmlwidgets where to look for the script and stylesheets
gLeafletPlugin <- htmlDependency("gLeaflet","1.9.0",
src = c(href = "https://cdnjs.cloudflare.com/ajax/libs/leaflet-plugins/1.9.0/layer/tile/"),
script = "Google.js")
# FIRST PLACE WHERE I AM STUCK: I am pretty sure, I also need to pass on
# the Google Maps API script reference before or along with the above command,
# but trying to include two htmlDependency objects together in a list, did not
# work. Maybe I wasn't doing it right.
# 2: Make a map and add the htmlDependency object to it
registerPlugin <- function(map, plugin) {
map$dependencies <- c(map$dependencies, list(plugin))
map
}
leaflet() %>%
setView(76.65, 12.32, zoom = 9) %>%
registerPlugin(gLeafletPlugin) %>%
# 3: Pass on custom JS logic: SECOND PLACE WHERE I AM STUCK
onRender("function(el, x) {
L.Google('TERRAIN').addTo(this);
}")
Would be grateful if someone could show me: (a) the correct way of registering the htmlDependency, when more than one script is involved; and (b) the correct syntax to call the extra JS logic needed to display a Google Terrain basemap.
Thanks!

Resources