admin管理员组文章数量:1356775
I'm using the leaflet package in R to generate a map with a large number of circles on it. The goal is a map I can publish to my website. The problem I'm having is that as I increase the number of circles, the resulting map loads very slowly, I get "unresponsive script" warnings and ultimately it pletely freezes up my browser.
I know this sort of thing is possible, because I've found a leaflet map that works the way I want mine to work:
I notice on the above map that the circles don't appear "clickable" like the circles on my map, and that they seem to load in square chunks. I have a hunch that these things are related to my problem. Unfortunately, I'm too much of a novice at leaflet/javascript stuff to figure this out on my own.
Here is a toy example illustrating my problem:
library("leaflet")
library("htmlwidgets")
dots <- data.frame(x=c(runif(10000, -93.701281, -93.533053)),
y=c(runif(10000, 41.515962, 41.644369)))
m <- leaflet(dots) %>%
addTiles('http://{s}.basemaps.cartocdn/dark_all/{z}/{x}/{y}.png') %>%
setView(-93.617167, 41.580166, zoom = 12) %>%
addCircles(~x, ~y, weight = 1, radius = 5,
color = "#FFA500", stroke = TRUE, fillOpacity = 0.1)
m
saveWidget(widget = m, file="example.html", selfcontained = TRUE)
I'm using the leaflet package in R to generate a map with a large number of circles on it. The goal is a map I can publish to my website. The problem I'm having is that as I increase the number of circles, the resulting map loads very slowly, I get "unresponsive script" warnings and ultimately it pletely freezes up my browser.
I know this sort of thing is possible, because I've found a leaflet map that works the way I want mine to work:
http://cartologic./geoapps/map_viewer/5/ny-crimes-2014-dot-density-map
I notice on the above map that the circles don't appear "clickable" like the circles on my map, and that they seem to load in square chunks. I have a hunch that these things are related to my problem. Unfortunately, I'm too much of a novice at leaflet/javascript stuff to figure this out on my own.
Here is a toy example illustrating my problem:
library("leaflet")
library("htmlwidgets")
dots <- data.frame(x=c(runif(10000, -93.701281, -93.533053)),
y=c(runif(10000, 41.515962, 41.644369)))
m <- leaflet(dots) %>%
addTiles('http://{s}.basemaps.cartocdn./dark_all/{z}/{x}/{y}.png') %>%
setView(-93.617167, 41.580166, zoom = 12) %>%
addCircles(~x, ~y, weight = 1, radius = 5,
color = "#FFA500", stroke = TRUE, fillOpacity = 0.1)
m
saveWidget(widget = m, file="example.html", selfcontained = TRUE)
Share
Improve this question
asked Feb 12, 2016 at 5:49
DWalDWal
2,76212 silver badges19 bronze badges
2
- cluster is a nice options (rstudio.github.io/leaflet/markers.html). Your example works very well! How many points are you talking about? – MLavoie Commented Feb 12, 2016 at 9:40
- @MLavoie Thanks for the suggestion. I messed around with cluster options and just couldn't get the performance I wanted. My example works well depending on the machine I use. But increasing the number of dots and you'll eventually hit a limit. I'm looking for something much more scalable to make large dot density maps. – DWal Commented Feb 15, 2016 at 8:41
4 Answers
Reset to default 3mapview can help you here. It builds upon the leaflet library for smaller data sets, but uses special javascript functionality for larger data.
your example with 1 Mio. points:
library(mapview)
library(sp)
dots <- data.frame(x=c(runif(1000000, -93.701281, -93.533053)),
y=c(runif(1000000, 41.515962, 41.644369)))
coordinates(dots) <- ~ x + y
proj4string(dots) <- "+init=epsg:4326"
mapview(dots)
It may still take a while to render, but once rendered it should be quite responsive. Note that mapview is designed to work with spatial* objects, that is why we need the calls to set the coordinate slot and the projection.
For more information have a look here:
http://environmentalinformatics-marburg.github.io/web-presentations/20150723_mapView.html
Hope that helps.
If you want to add a large number of vector objects to a map, it is rare that it can be done easily.
Notice that the raster data is broken into tiles so that all the information does not have to be shown at one time. For your vector data (in this case, circles) you have to do the same thing.
Basically what I like to do is to break the large data set into smaller (vector) tiles, with the same boundaries as the raster tiles you are showing. Duplicate the data if you want it to appear at several zoom level. As you are showing circle, imagine that you partition the circles' center points on the tile boundary.
I have an application similar to this where I basically partition my vector data on tile boundaries and store the information in geojson files. When I get an event that the raster tile has been loaded I can then load the equivalent vector file as a geojson layer (same thing when the raster tile is unloaded). In this way, you can limit the amount of vector data that has to be displayed at any one time.
If you have a lot of points, they are not really going to be visible at low zoom levels anyway, so it might be better just to show them at an appropriate zoom level (perhaps with a different representation at low zooms - like a heat map). This will keep the amount of data being shown at any one time lower.
Since this question has a few upvotes, I'll generally describe both of the solutions I found. Maybe if I have time later I'll get all the files together on GitHub.
First, I found TileMill. Simply load a data file of coordinates into TileMill, style the way you want them to appear, and output tiles (png). Host those tiles on the web somewhere and load them with leaflet. This process was a bit too manual for my liking because TileMill kept crashing when I loaded in csv files that were too large for it to render on my machine.
I found the best solution was use Processing, adapting Robert Manduca's code here: https://github./rmanduca/jobmaps. I don't use Python so I rewrote those parts in R and modified the Processing code according to my specifications.
Mapdeck (released on CRAN Aug 2018) uses WebGL (through Deck.gl) and is designed to handle millions of points (depending on your system's hardware of course)
library(mapdeck)
set_token("MAPBOX_TOKEN")
n <- 1e6
dots <- data.frame(x=c(runif(n, -93.701281, -93.533053)),
y=c(runif(n, 41.515962, 41.644369)))
dots$letter <- sample(letters, size = n, replace = T)
mapdeck(
style = mapdeck_style('dark')
) %>%
add_scatterplot(
data = dots
, lon = "x"
, lat = "y"
, fill_colour = "letter"
, radius = 5
, fill_opacity = 50
, layer_id = "dots"
)
本文标签:
版权声明:本文标题:javascript - How do I create a leaflet map with thousands of marks that doesn't crash my browser? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744046247a2581575.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论