Closed helgasoft closed 1 year ago
This looks good, many thanks @helgasoft! Do you have a working version starting with an sf
object? sf supersedes sp so support for it would make this solution much more future-proof. Good news: switch from sp to sf should be easy and I can provide pointers if you need them.
Here is one way of getting the data through sf.
library(sf)
fname <- system.file("shape/nc.shp", package="sf")
nc <- st_read(fname)
dats <- list()
for(i in 1:nrow(nc)) {
geom <- as.data.frame(nc$geometry[[i]][[1]][[1]])
coords <- list()
for(k in 1:nrow(geom))
coords <- append(coords, list(c(geom$V1[k], geom$V2[k])))
dats <- append(dats, list(list(name= nc$NAME[i], coords=coords)))
}
centr <- as.data.frame(nc$geometry[[1]][[1]][[1]])
library(echarty)
p <- ec.init(load='leaflet')
p$x$opts$series <- list(
list(type='lines', coordinateSystem='leaflet', polyline= TRUE,
lineStyle= list(width=3), color= 'red', name= 'counties',
data= dats
))
p$x$opts$tooltip <- list(show= TRUE)
p$x$opts$legend = list(show= TRUE)
p$x$opts$leaflet$center <- c(mean(centr[,1]), mean(centr[,2]))
p$x$opts$leaflet$zoom <- 6
p
Previous example is with polylines. This one - with filled polygons. Tooltips show each polygon's name which is a county name from the sf shape data.
library(sf)
fname <- system.file("shape/nc.shp", package="sf")
nc <- st_read(fname)
cntis <- list() # counties
for(i in 1:nrow(nc)) {
geom <- as.data.frame(nc$geometry[[i]][[1]][[1]])
coords <- list()
for(k in 1:nrow(geom))
coords <- append(coords, list(c(geom$V1[k], geom$V2[k])))
cntis <- append(cntis, list(list(
type= 'custom', coordinateSystem= 'leaflet',
name= nc$NAME[i], # county name for tooltip
renderItem= htmlwidgets::JS('riPolygon'),
itemStyle= list(opacity= 0.3),
tooltip= list(formatter= '{a}'),
data= coords)))
}
centr <- as.data.frame(nc$geometry[[1]][[1]][[1]])
library(echarty)
p <- ec.init(load= c('leaflet', 'custom'),
series= cntis,
tooltip= list(show= TRUE)
)
# update leaflet presets
p$x$opts$leaflet$center <- c(mean(centr[,1]), mean(centr[,2]))
p$x$opts$leaflet$zoom <- 6
p
Nice! Could there be a function to visualise it in a single command, e.g. ec.sf(nc)
Implemented in latest echarty v.1.5.6.02. Check new command ?ec.util. See also more code and demo clip.
library(sf); library(echarty)
fname <- system.file("shape/nc.shp", package="sf")
nc <- as.data.frame(st_read(fname))
ec.init(load= c('leaflet', 'custom'), # always load custom for polygons
js= ec.util(cmd='sf.bbox', bbox=st_bbox(nc$geometry)),
series= ec.util(df= nc, nid= 'NAME', itemStyle= list(opacity= 0.3), verbose=TRUE),
tooltip= list(formatter= '{a}')
)
# scatter points can have a common name set for legend, no need for _nid_ param
fn <- ec.util(cmd= 'sf.unzip',
url= 'https://mapcruzin.com/sierra-leone-shapefiles/points.zip')
nc <- as.data.frame(st_read(fn))
ec.init(load= c('leaflet'),
js= ec.util(cmd= 'sf.bbox', bbox= st_bbox(nc$geometry)),
series= ec.util(df= nc, name= 'spots', itemStyle= list(color= 'red'), verbose=TRUE),
tooltip= list(formatter= '{a}'), legend= list(show= TRUE)
)
leaflet with timeline, for @leovan
tmp <- '
lng,lat,name,date,place
-118.808101,32.843715,"Seabed","2021-02-02","location A"
-117.332678,34.845565,"Lancaster","2021-04-02","location A"
-116.127504,32.846118,"fwy #8","2021-04-02","place B"
-117.316886,30.961700,"Baja","2021-07-02","place B"'
df <- read.csv(text= tmp, header= TRUE)
library(echarty)
df |> dplyr::group_by(place) |> ec.init(
load= 'leaflet',
leaflet= list(layerControl= list(position= 'topright'),
tiles= list(
list(
label= 'Open Street Map',
urlTemplate= 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
options= list(attribution= '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>')
),
list(
label= 'Stamen',
urlTemplate= 'https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}{r}.{ext}',
options= list(attribution= 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>',
subdomains= 'abcd', maxZoom= 18, ext= 'png')
)
)
),
tl.series= list(type= 'scatter', coordinateSystem= 'leaflet',
symbolSize= 15,
encode= list(lng= 'lng', lat= 'lat', tooltip= c(3,4))),
tooltip= list(show= T), color= 'red'
)
if you like this solution, please consider granting a Github star ⭐ to echarty.
Proof of concept - Leaflet map with shapefile polylines. Idea from @Robinlovelace. We prefer Leaflet map as most versatile. Other options are 'bmap' and gmap, which are based on Baidu and Google and require an API key.
If you like this solution, please consider granting a Github star ⭐ to echarty.