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
Related
I have created some tiles out of a very large raster using the Qtiles plugin in Qgis. I have saved them to a local directory on my computer, and now want to render them in a leaflet map using R.
The addTiles function passes a URL, but doesn't seem to work with a local filepath. In a different post (How to render custom map tiles created with gdal2tiles in Leaflet for R?), Lauren recommends using a www folder inside the shiny directory. Firstly, I'm not 100% sure what is meant by that, and secondly I don't know if that solution is applicable to what I'm trying to do; all I want to do is render these tiles in a leaflet map object and save it locally as html. Is it possible to do what I am attempting?
The code looks something like this:
library(leaflet)
map <- leaflet()
map <- addProviderTiles(map, "CartoDB.Positron")
map <- addTiles(map, "C:/mapTiles/level100Tiles/{z}/{x}/{y}.png")
Is there a different leaflet function for this specific purpose that I am not aware of? Or is it just not something that's done?
Thanks :)
Add a ResourcePath inside server and it'll work, no need for the www folder anywhere. Source.
server <- function(input, output, session) {
addResourcePath("mytiles", "C:/Users/.../mapTiles")
output$map <- renderLeaflet({
leaflet() %>%
addTiles(urlTemplate = "/mytiles/{z}/{x}/{y}.png")
})
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.)
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!
I'm looking for guidance on getting a basic example of leafletR package to show a map in the browser. Working with the most basic example, the map doesn't show up in the browser. I've checked the .html and .json files, which are present and appear to properly formatted. Javascript inspector shows this error:
XMLHttpRequest cannot load file:///var/folders/_0/tdgf_k7x77qdn64_gk9ynljm0000gp/T/Rtmp6O4QZM/Fiji_Earthquakes/quakes.geojson. Received an invalid response. Origin 'null' is therefore not allowed access.
I'm on a Mac: OSX 10.7.5
RStudio Version: 0.98.857
Code
library(leafletR)
data(quakes)
# store data in GeoJSON file (just a subset here)
q.dat <- toGeoJSON(data=quakes[1:99,], dest=tempdir(), name="quakes")
# make style based on quake magnitude
q.style <- styleGrad(prop="mag", breaks=seq(4, 6.5, by=0.5), style.val=rev(heat.colors(5)), leg="Richter Magnitude", fill.alpha=0.7, rad=8)
# create map
q.map <- leaflet(data=q.dat, dest=tempdir(), title="Fiji Earthquakes", base.map="osm", style=q.style, popup="mag")
# view map in browser
browseURL(q.map)
Thank you in advance for any advise.
A quick solution to open the map using a local web server is to take advantage of RStudio's HTML viewer.
rstudio::viewer(qmap)
The trick is to include incl.data=TRUE in the leaflet function. For example,
map<-leaflet(data=leafdat, dest=downloaddir, style=sty,
title="index", base.map="osm",
incl.data=TRUE, popup=popup)
Check out this post that shows how to do this in detail.
I'm having some issues displaying an interactive map in R-Shiny that incorporates a KML file. I installed leaflet-plugins and was able to create an HTML file that displays properly by itself in the browser but not within Shiny. This attempt followed an example here - the code is available if you view source.
Because this initial version does not require the HTML itself to change, I attempted to follow the samples here to include the raw HTML in my page but I receive a 404 error with these as well as when I attempted to include it as an iframe within R-Shiny (following this discussion). I then set up an external facing server for both the KML file and the HTML file and got the same result.
I was able to get a map working without the KML file with leaflet-shiny but I'm frankly not sure how to add the KML file and don't see this in the documentation.
Finally, I tried rMaps which does have a "addKML" method, but I can't get it working with various locations of files on my server (
map1 = Leaflet$new()
map1$setView(c(45.5236, -122.675), 13)
map1$tileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")
map1$addKML('http://kml-samples.googlecode.com/svn/trunk/kml/Placemark/placemark.kml')
map1
It works without the $addKML line. It might be worth noting that the tilelayer line on example 1 here also resulted in a blank map.
I actually have some possibly similar issues hosting derived title layers that are still unresolved which is one reason I opted for uses KML layers for this demo version of the application, which is why I tagged networking on here as well. I'm using Digital Ocean.
Thank you for any thoughts or pointers you may have.
I think there may be a small issue in the rMaps library. If you inspect the config.yml file
https://github.com/ramnathv/rCharts/blob/master/inst/libraries/leaflet/config.yml you will see that for
content delevery network (cdn) there is reference to
"http://harrywood.co.uk/maps/examples/leaflet/leaflet-plugins/layer/vector/KML.js". This KML reader is a plugin for leaflet from https://github.com/shramov/leaflet-plugins/blob/master/layer/vector/KML.js. When content is delivered locally:
css: [external/leaflet.css, external/leaflet-rCharts.css, external/legend.css]
jshead:
- external/leaflet.js
- external/leaflet-providers.js
- external/Control.FullScreen.js
there is no reference to this javascript file. We can fix this:
require(yaml)
leafletLib <- file.path(find.package("rMaps"), "libraries", "leaflet")
rMapsConfig <- yaml.load_file(file.path(leafletLib, "config.yml"))
# add a kml library
kmlLib <- readLines("http://harrywood.co.uk/maps/examples/leaflet/leaflet-plugins/layer/vector/KML.js")
write(kmlLib, file.path(leafletLib, "external", "leaflet-kml.js"))
# add the library to config.yml
rMapsConfig$leaflet$jshead <- union(rMapsConfig$leaflet$jshead , "external/leaflet-kml.js")
write(as.yaml(rMapsConfig), file.path(leafletLib, "config.yml"))
Now the config.yml will contain the necessary link to the KML reader and there is a local copy stored now in external/leaflet-kml.js. Our example still wont work however as we will get a Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://kml-samples.googlecode.com/svn/trunk/kml/Placemark/placemark.kml. This can be fixed by moving the resource to the same domain or enabling CORS.
We will need to have this file served locally. We can place it as a temporary measure in the leaflet folder in the rMaps package. When a map is created this folder gets copied to a temporary file:
require(rMaps)
map1 = Leaflet$new()
map1$setView(c(45.5236, -122.675), 13)
map1$tileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")
map1$addKML('leaflet/placemark.kml')
# temp copy http://kml-samples.googlecode.com/svn/trunk/kml/Placemark/placemark.kml
# to rMaps
sampleKml <- readLines('http://kml-samples.googlecode.com/svn/trunk/kml/Placemark/placemark.kml')
write(sampleKml, file.path(leafletLib, 'placemark.kml'))
# finally try the map
map1
# remove the temp file
file.remove(file.path(leafletLib, 'placemark.kml'))
UPDATE:
There is an addAssets method in rCharts which allows you to add .js files. This allows us to simpilfy things and doesnt require us to write a copy of the js file nor edit the config.yml file.
require(rMaps)
map1 = Leaflet$new()
map1$setView(c(45.5236, -122.675), 13)
map1$tileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")
map1$addAssets(css = NULL, jshead = 'http://harrywood.co.uk/maps/examples/leaflet/leaflet-plugins/layer/vector/KML.js')
map1$addKML('leaflet/placemark.kml')
leafletLib <- file.path(find.package("rMaps"), "libraries", "leaflet")
sampleKml <- readLines('http://kml-samples.googlecode.com/svn/trunk/kml/Placemark/placemark.kml')
write(sampleKml, file.path(leafletLib, 'placemark.kml'))
# finally try the map
map1
# remove the temp file
file.remove(file.path(leafletLib, 'placemark.kml'))