简体   繁体   中英

Problems loading 2 GeoJSON files into a leaflet web map in R using the leafletR package

I'm using the leafletR package ( http://cran.r-project.org/web/packages/leafletR/index.html ) to make a leaflet webmap applet, but having trouble loading 2 sets of features onto the same map.

As I understand it, the leaflet() function will only accept GeoJSON files of one geometry type.

I therefore have 2 separate GeoJSON files, one with MultiPolygons and another with Points.

I'm able to get the MultiPolygons to render as a choropleth with this code:

#Load LeafletR
require(leafletR)

#Create quantiles
cuts <- round(quantile(UKpostcode_areas$data, probs = seq(0, 1, 0.20), na.rm = FALSE), 0)
cuts[1] <- 0 #We don't want any negative values, so let's make the first cut zero

#Fields to include in the popup
popup.1 <- c("name", "data")

#Graduated style based on an attribute
sty.1 <- styleGrad(prop = "data", breaks=cuts, right=FALSE, style.par="col", style.val=rev(heat.colors(6)), leg="Data", lwd=1)

#Create the map and load into browser
map <- leaflet(data = "map/UKpostcode_areas.geojson", dest = "map", style = sty.1, title = "UKpostcode_areas_choropleth", base.map= "osm", incl.data=TRUE,  popup = popup.1)

I'm also able to get the Points to render:

#Create new style and popup details for the 2nd layer
sty.2 <- styleSingle(col = "white", fill = "#2b83ba", fill.alpha = 1, rad = 3)
popup.2 <- c("name", "trust")

#Let's take a look at the map of hospitals
map2 <- leaflet(data="map/hospitals.geojson", dest = "map", style = sty.2, popup = popup.2, title = "hospitals", base.map = "osm", incl.data=TRUE, controls = "all")
browseURL(map2)

However, when I try to render both on the same Leaflet map, it just gives me a blank screen:

#Now we can combine the 2 into 1 map, this is problematic, can't get it to work!
map3 <- leaflet(data = list("map/UKpostcode_areas.geojson", "map/hospitals.geojson"), style = list(sty.1, sty.2), dest = "map", title = "index", base.map= "osm", incl.data=TRUE, controls = "all")
browseURL(map)

I suspect there's something wrong with the last couple of lines of code. But I can't figure out what.

I believe LeafletR can only handle multiple layers when there is a single style for each layer.

Example from the leaflet() documentation page :

# more than one data set
park <- toGeoJSON(data=system.file(package="leafletR", "files", 
  "park_sk.zip"), dest=tempdir())
peak <- toGeoJSON(system.file(package="leafletR", "files", "peak_sk.kml"), 
  dest=tempdir()) # httr package required
sty.1 <- styleSingle(col="green", fill="green")
sty.2 <- styleSingle(col="brown", fill="brown", rad=3)
map <- leaflet(data=list(park, peak), dest=tempdir(), 
  style=list(sty.1, sty.2))
browseURL(map)

This works as expected, but if you change sty.2 to a graduated style, eg:

sty.2 <- styleGrad(prop="Name", col="brown", fill="brown", style.par="rad",
     style.val=c(1,10), breaks=breaks, right=TRUE, out=1)

it gives the same blank screen you described (though it works fine if peak is the only layer). I'm not sure how crucial it is that your map has a graduated style, but if you use styleSingle() , both layers should appear.

What i'm thinking (guessing actually, i'm by no means familiar with R) is that combining those two GeoJSON files won't work if they're actually FeatureCollections. A FeatureCollection would look something like this:

{
    "type": "FeatureCollection",
    "features": [{
        // Feature
    }, {
        // Another feature
    }]
}

Now if you combine two of those you'll end up with something like this:

[{
    "type": "FeatureCollection",
    "features": [{
        // Feature
    }, {
        // Another feature
    }]
}, {
    "type": "FeatureCollection",
    "features": [{
        // Feature
    }, {
        // Another feature
    }]
}]

Leaflet's L.GeoJSON layer won't take that. What you want to do is merge the embedded feature arrays, and embed that into a new FeatureCollection object or just merge the two feature arrays into one new array and use that. L.GeoJSON can use a FeatureCollection or an array of features. But it won't take an array of FeatureCollections and thats what i think you are doing now.

In JS i would do something like this:

var collectionA = { //FeatureCollection };
var collectionB = { //FeatureCollection };

var features = collectionA.features.concat(collectionB.features);

var collection = {
    "type": "FeatureCollection",
    "features": features
}

// Now you can use: 
new L.GeoJSON(features);
// Or you can use:
new L.GeoJSON(collection);

Another way is to use the addData method of L.GeoJSON but i wouldn't know if that's available to you when using LeafletR, but in JS we can do:

var collectionA = { //FeatureCollection };
var collectionB = { //FeatureCollection };

var layer = new L.GeoJSON();

layer.addData(collectionA);
layer.addData(collectionB);

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM