本文是时空维度挖掘系列的第二篇,将引进空间挖掘中的重量级嘉宾 leaflet。在互联网竞争日益激烈的今天,一方面,online业务蓝海愈来愈少,扩展成本也愈来愈高,许多互联网企业开始介入地推,甚至出现了好比望京扫码一条街这样的经典案例;另外一方面,offline的传统行业在经历这几年的洗礼,不断增强线下精细化运营的基础设施,支付宝微信支付走进街边小店。打通线上线下的供应链一体化,成为了BAT以外的几乎惟一机会,也就是马云口中所谓的新零售。在这样的机会窗口下,在地图的基础设施上孕育出了像 AirBnb、Uber、滴滴、美团、饿了吗等等新时代独角兽。html
咱们能够预见,当下掌握空间维度挖掘对于洞察新零售时代经济走向很是重要,本文将简单介绍空间维度挖掘中的一些经常使用工具,并重点介绍空间可视化框架leaflet。前端
对于空间数据挖掘的一些入门介绍能够参考此文:R空间数据处理与可视化git
leaflet.js 是一个现代面向用户体验的轻量GIS库,适用于免费、专业、快速的地图原型开发,拥有丰富第三方插件生态系统,已经成为数据科学在空间数据可视化领域的事实标准,至关于GIS中的ggplot
。github
R 中的leaflet 包是由 RStudio 公司制做的leaflet.js封装,在此基础上还有若干 leaflet 插件,好比leaflet.esri、leaflet.extras 能够提供诸如热力图之类的高级功能等。web
leaflet 主要包含了下面9个核心要素算法
经过图层的叠加,咱们能够根据自身需求观测到不一样维度的数据变化状况,图层的基本格式以下:shell
http://{s}.tile.osm.org/{z}/{x}/{y}.png
s
表示图层提供方来源z
表示zoom缩放的比例x
表示经度y
表示纬度其中zoom的范围在[0,20],其中0表示整个世界,13表示乡镇街道,19表示最小单位像素,一般图层由256x256的png图片拼接起来。json
目前,leaflet 经过addTiles()
函数便可实现图层添加,默认的图层提供方是 OpenStreetMap 简称OSM
,一样咱们能够添加高德地图、百度地图、MapBox、ESRI等等或自定义,这里以高德地图为例(再次感谢高德数据分析师):segmentfault
x =116.310003 y =39.991957 leaflet() %>% addTiles( 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', tileOptions(tileSize=256, minZoom=9, maxZoom=17), attribution = '© <a href="http://ditu.amap.com/">高德地图</a>', ) %>% # 添加高德底图 也能够用 leafletCN::amap() 代替 setView(lng = x,lat = y,zoom = 13) %>% # 设置默认视角 addMarkers(lng = x,lat=y)%>% # 添加标记点位 addGraticule(interval = 0.01,group = "graticule") %>% # 经纬网格 addLayersControl( overlayGroups = c("graticule"), options = layersControlOptions(collapsed = FALSE) ) # 分组控制
更进一步,图层数量增长,须要分组的时候,就涉及到多组图层的控制。经过addLayersControl
来增长图层的分组控制能力。后端
图层服务器能够做为单独的一项服务来定制后端服务,而后经过分享相应的图层再叠加的方式加速前端呈现的性能。
leaflet 中提供许多与shiny结合的事件控制特性,好比对不一样leaflet对象的点击、悬停、双击等等。
经过 leafletProxy()
能够对 leaflet 地图对象作额外的操做,好比切换图层,添加图层 addXXX,移除图层 clearXXX。
假设如今经过 leaflet 地图对象Id 为 map:
leafletOutput("map", width = "100%", height = "100%")
leaflet 交互事件 遵循这个命名规则: input$MAPID_OBJCATEGORY_EVENTNAME
,
对应的输出为一个list,好比
{ "lat":23.12321, "lng":123.123123, "id":"map", "featureId":"xxx", # 只有geojson才有 "properties":"xxx" # 只有geojson才有 }
那么能够经过下面代码捕捉对应事件:
input$map_shape_click # 获取多边形点击 input$map_marker_click # 获取标识点击 input$map_geojson_click # 获取geojson点击 input$map_topojson_click # 获取 topojson点击 input$map_click # 任意点击地图位置 返回经纬度和图层id,以list的形式返回, input$map_mouseover # 鼠标悬停 input$map_mouseout # 鼠标移出 input$map_bounds # 地图视野边界, 经过bounds 能够控制数据只显示视野内来加快数据渲染效果。返回的结果以 north, east, south, west 的一组list呈现 input$map_zoom # 返回视野深度 一般在 0-19之间
目前 leaflet.extras 也支持更多的插件中的事件。好比能够经过多边形的编辑实现地理围栏:
leaflet::leaflet() %>% leafletCN::amap()%>% leaflet::setView(lng = 116,lat = 39, zoom = 12) %>% addDrawToolbar( targetGroup='draw', editOptions = editToolbarOptions(selectedPathOptions = selectedPathOptions())) %>% addLayersControl(overlayGroups = c('draw'), options = layersControlOptions(collapsed=FALSE)) %>% addStyleEditor()
# 经过 input$MAPID_draw_all_features 会返回地理围栏的相关信息 # input$MAPID_draw_start 返回 绘制开始 信息 # input$MAPID_draw_stop 返回 绘制中止 信息 # input$MAPID_draw_new_feature 返回 建立绘制 信息 # input$MAPID_draw_edited_features 返回 编辑绘制 信息 # input$MAPID_draw_deleted_features 返回 删除绘制 信息 observeEvent(input$map_draw_all_features,{ #print("All Features") num_features <- length(input$map_draw_all_features$features) if (is.null(unlist(input$map_draw_all_features$features[num_features]))){ return(NULL) }#判空 if(input$map_draw_all_features$features[[num_features]]$properties$feature_type != 'polygon') { return(NULL) } cords_list <- input$map_draw_all_features$features[[num_features]]$geometry$coordinates[[1]] })
这里有一个用于表述地理数据的特殊数据框,被称为 SpatialPointsDataFrame,经过它能够实现空间几何中点、线、面的表达。
它主要有下面5个部分组成:
空间计算中点、线、面的数据