日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

【Shiny】基于R-Shiny制作地图App(百度地图)

發(fā)布時間:2024/3/26 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Shiny】基于R-Shiny制作地图App(百度地图) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

估計每個愛好編程的都想某天可以開發(fā)出一個專屬于自己的軟件or應(yīng)用,在下也是。然而由于當(dāng)初入門編程的時候偷懶特地避開了那些以開發(fā)為目的源代碼級的語言(比如說java,C和C++)而選擇了R,我離這個目標(biāo)估計是越走越遠(yuǎn)了。雖然R語言擁有自己的GUI開發(fā)工具,但是由于不能封裝所以只能給留給自己看。不過好在Rstudio公司開發(fā)的Shiny包可以基于R語言制作web端的APP,依托于互聯(lián)網(wǎng),算是間接實(shí)現(xiàn)了封裝并傳播的功能。不過shiny所實(shí)現(xiàn)的web app只能實(shí)現(xiàn)些比較簡單的功能,設(shè)計出來的初衷是為了在結(jié)果展示的時候作為Data Product來保證展示的過程更流暢更直觀。所以想做游戲的還是安心學(xué)java吧。這次想分享的是我自己閑著沒事兒整出來的一個閹割版的百度地圖,照著Shiny Gallery里面的某些大神那里得到的靈感,閑著沒事兒去里面轉(zhuǎn)轉(zhuǎn),確實(shí)可以學(xué)到很多東西。

Shiny

Shiny在這里就不過多介紹了,簡言之他就是一個可以將R代碼的架構(gòu)轉(zhuǎn)換為HTML架構(gòu)的神奇的東西,換言之就是某尊大神將HTML給封裝成了R語言的一個包大概的工作原理是這樣的




一般網(wǎng)頁開發(fā)分為前段和后端,前端差不多就是網(wǎng)頁里的那些圖標(biāo)啊排版啊啥的,后端就是在你對網(wǎng)頁進(jìn)行操作時,網(wǎng)頁該如何進(jìn)行反饋的交互邏輯。一般即使有HTML文件也是用不了的,因?yàn)闆]有后端的話這網(wǎng)頁除了看沒什么用,不過牛逼的是Shiny還能幫你把后端給組織好。跟web開發(fā)類似,Shiny包里的架構(gòu)邏輯也是需要分好前端和后端的,分別用 ui.R和 server.R兩個文件來儲存。先來個簡單的:

Sample 1

這是一個用來反映Kmeans均值聚類實(shí)時效果的簡單應(yīng)用,可以自己DIY中心點(diǎn)個數(shù)以及要聚類的兩個變量,數(shù)據(jù)集是鳶尾花。
界面是這樣的,目前這圖里反應(yīng)的是將Sepal.Length和Sepal.Width分為3類后,樣本分布情況。




代碼也分為前端和后端,前端是ui,后端是sever

## The UI of the web library(shiny) library(ggplot2)ui <- shinyUI(fluidPage(headerPanel(title = 'Test Kmeans'),sidebarPanel(selectInput(inputId = 'Col',label = 'The Variables',choices = c('Sepal.Length','Sepal.Width','Petal.Length','Petal.Width'),selected = c('Sepal.Length','Sepal.Width'),multiple = T),numericInput(inputId = 'center',label = 'Centroids',value = 3,min = 1,max = 10,step = 1),submitButton(text='submit')),mainPanel(h1('The result of Kmeans'),plotOutput(outputId = 'plot')) ))## The server of the web server <- shinyServer(function(input,output){output$plot <- renderPlot({da <- iris[,input$Col]fit <- kmeans(da,centers = input$center)da$cluster <- fit$clusterda2 <- as.data.frame(fit$centers)ggplot()+geom_point(data = da,aes(x=da[,input$Col[1]],y=da[,input$Col[2]],color=factor(cluster)))+geom_point(data = da2,aes(x=da2[,names(da2)[1]],y=da2[,names(da2)[2]],color=factor(1:nrow(da2))),size=5,shape=3)+xlab(input$Col[1])+ylab(input$Col[2])}) })## Run the app shinyApp(ui = ui,server = server)

總結(jié)來說就是ui里確定了在哪里input和output,server里通過input里的value來轉(zhuǎn)換為output,調(diào)用的原則是inputidoutputid,通過設(shè)定的id來一一對應(yīng),跟R6的面向?qū)ο缶幊桃粋€架構(gòu)方式。

地圖

完成這個app還有一個要素就是地圖。在各種涉及到“位置”的數(shù)據(jù)分析中,地圖在可視化中都扮演著一類非常重要的角色。有時候即使是一個很簡單的分析,配上地圖可視化之后就會十分的高大上。雖然R語言中的ggplot2等包可以根據(jù)地圖邊界坐標(biāo)來畫出來地圖,但是都是靜態(tài)的地圖,所以我們使用的是R語言中一個公共地圖的接口leaflet。只需要幾行代碼就可以創(chuàng)建一個基礎(chǔ)的地圖層

library(leaflet) m <- leaflet() m%>%addTiles()

與ggplot2挺像的,先畫一個底,如果想diy的話,再自己往上加圖層,而且最重要的是地圖是動態(tài)的而且可交互!比如說下面這兩張圖。

如果我想將某個位置的坐標(biāo)給標(biāo)出來的話,就需要用額外的函數(shù)了

library(leaflet) m <- leaflet() m %>% addTiles() %>% ## 給某個經(jīng)度和緯度做標(biāo)記addPopus(lng=longtitude,lat=latitude)

坐標(biāo)數(shù)據(jù)

有了框架有了地圖,接下來還差坐標(biāo)數(shù)據(jù)了。對于個人來講,一個涵蓋全球各地坐標(biāo)的數(shù)據(jù)庫還是不現(xiàn)實(shí)的,所以就需要借用一些已有的成型的地圖數(shù)據(jù)庫,比如說百度地圖和谷歌地圖,可惜后者被墻了。這里再介紹一個R包,名字就叫作baidumap,可以通過調(diào)用百度地圖的API來獲取某個地址的經(jīng)緯度以及路線,輸出的結(jié)果是json格式(可選),所以這意味著我們還需要通過調(diào)用rjson包來解析json格式的文件。示例如下

library(baidumap) library(rjson)## 獲取“北京大學(xué)”的坐標(biāo) m <- getCoordinate(address='北京大學(xué)')

然后我們會獲得這樣格式的數(shù)據(jù)

{"status":0,"result":{"location":{"lng":116.31616663593383,"lat":39.997752940431137},"precise":0,"confidence":50,"level":"UNKNOWN"}}

通過函數(shù)fromJSON(m)格式就會變的更合理一點(diǎn),在R里面會以list形式表示。

$status [1] 0$result $result$location $result$location$lng [1] 116.3162$result$location$lat [1] 39.99775$result$precise [1] 0$result$confidence [1] 50$result$level [1] "UNKNOWN"

這是一個list格式數(shù)據(jù),我們可以直接用美元符號($)來調(diào)用里面的子元素,其中status表示反饋狀態(tài)(0表示成功,1表示找不到,2表示沒有輸入地點(diǎn)),lng和lat就不解釋了,level表示地點(diǎn)的等級,不過只局限于“城市,區(qū)縣”這些比較宏觀的。

該包還有另外一個強(qiáng)大的函數(shù)是getRoute(origin,destination)可以獲得兩點(diǎn)之間的路線的坐標(biāo),配合上前面leaflet中的一個addPolyline()函數(shù),可以在地圖上標(biāo)注出路線圖。

整合

所有要素都配齊了,接下來的任務(wù)是將他們幾個整合在一起了,直接上代碼。

library(shiny) library(leaflet) library(baidumap) library(rjson)ui <- shinyUI(fluidPage(## the area for titleheaderPanel(title = 'Simulated BaiduMap'), ## plot the leaflet in the whole pageleafletOutput(outputId = 'map',width = '1920px',height = '1080px'),## control inputs panel and buttonabsolutePanel(width = 430,top=200,left = 'auto',draggable = T,textInput(inputId = 'Loc',label = 'THE PLACE'),textInput(inputId = 'Start',label = 'FROM',width = "50%"),textInput(inputId = 'End',label = 'TO',width = "50%"),selectInput(inputId = 'selected',label = 'Route or Loc',choices = c('Loc','Route'),selected = 'Loc',multiple = F),textOutput(outputId = 'Request'),submitButton(text = "Submit")) ))server <- shinyServer(function(input, output) {## acquire the coordinate from rjson filegetcoord <- function(x){## x is a name of some placex <- fromJSON(getCoordinate(x))return(x)}## output leaflet map to the id:mapoutput$map <- renderLeaflet({m <- leaflet()m <- m%>%addTiles()if(input$selected == 'Loc'){temp <- getcoord(input$Loc)if(temp$status!=0){output$Request <- renderText({c('The location failed to be found')})m}else{output$Request <- renderText({c('The location is found successfully')})m %>% addMarkers(lng=temp$result$location$lng,lat=temp$result$location$lat,popup = paste0(input$Loc,'--',temp$result$level))}}else{temp1 <- getcoord(input$Start)temp2 <- getcoord(input$End)if(temp1$status==0&temp2$status==0){output$Request <- renderText({c('Both start point and end point are valid')})route <- getRoute(input$Start,input$End)m%>%addPolylines(route$lon,route$lat)%>%addMarkers(lng=route$lon[c(1,nrow(route))],lat=route$lat[c(1,nrow(route))],popup = c(paste0(input$Start,'--',temp1$result$level),paste0(input$End,'--',temp2$result$level)))}else{output$Request <- renderText({c('One or both of origin and destination is invalid')})}}}) })

就不解釋代碼了,主要兩種功能

  • 輸出定點(diǎn)坐標(biāo):將Route or Loc設(shè)為Loc,然后在THE PLACE里輸入目標(biāo)地點(diǎn),然后submit就OK
  • 輸出兩點(diǎn)路線:將Route or Loc設(shè)為Route,然后分別在FROM和TO里輸入起始點(diǎn)和終點(diǎn),然后submit
  • 效果還是蠻好的,比如說我想找天安門到清華大學(xué)的路線:

    總結(jié)

    博客原文還是發(fā)在了個人網(wǎng)頁上Zhuifengmu,如果感興趣的話可以嘗試下我之前發(fā)布的一個粗糙版本的ChinaMap,由于是國外的網(wǎng)不一定登的上去。文章是水出來的并沒有注重細(xì)節(jié),歡迎指正。

    總結(jié)

    以上是生活随笔為你收集整理的【Shiny】基于R-Shiny制作地图App(百度地图)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。