2016-12-06 9 views
0

このシンプルな光沢のあるアプリでは、マップをドラッグして重心が地図中心に最も近い郵便番号を表示できます。R Shiny/Leaflet:地図中心に最も近い地点を選択

問題は、マップセンターに最も近い郵便番号を保持する反応性オブジェクトが、アプリケーションの初期化時に郵便番号を読み込んで変更しないことです。

一方、地図の枠内にすべての郵便番号の重心を表示すると、予想どおりに機能します。どちらの表現も非常によく似ていますが、一方の表現は動作しますが、他方の表現は動作しません。

何が起こっているのですか?

再現コード:

library(shiny) 
library(leaflet) 

# List of ZIP code centroids as X/Y coordinates 
zip_coord <- read.csv('https://www.dropbox.com/s/lz9gmrz5skvef53/zip_coord.csv?dl=1') 

# Default view location 
lat <- 42.361145 
lng <- -71.057083 
zoom <- 11 



ui <- shinyUI(fluidPage(fluidRow(
    column(
    7, 
    offset = 1, 
    leafletOutput("map", height = "700")), 
    column(
    3, 
    h5("This doesn't work: It always shows the same ZIP:"), 
    tableOutput("centerZip"), 
    br(), 
    h5("This works: the ZIPs change as you move the map around:"), 
    tableOutput("inBoundsZIPs") 
) 
))) 


server <- (function(input, output, session) { 

    output$map <- renderLeaflet({ 

    leaflet() %>% 
     addProviderTiles("Stamen.TonerLite", group = "Stamen.TonerLite") %>% 
     setView(lat = lat, 
       lng = lng, 
       zoom = zoom) 
    }) 


    # A reactive expression that returns a single zip code, the one closest to the center 
    # of the current map view 
    # THIS DOES NOT WORK AS EXPECTED 

    centeredZip <- reactive({ 
    if (is.null(input$map_bounds)) 
     return(NULL) 
    bounds <- input$map_bounds 
    center <- c(mean(bounds$north, bounds$south), 
       mean(bounds$east, bounds$west)) 

    nearest.zip <- zip_coord[which.min(colSums((t(zip_coord[-1]) - center)^2)),1] 
    # Pick out the point 
    subset(zip_coord, ZIP == nearest.zip) 

    }) 

    output$centerZip <- renderTable({ 
     centeredZip() 
    }) 

    # A reactive expression that returns the set of zips that are 
    # within the current view bounds 
    # THIS WORKS AS EXPECTED 

    zipsInBounds <- reactive({ 
    if (is.null(input$map_bounds)) 
     return(zip_coord[FALSE,]) 
    bounds <- input$map_bounds 
    latRng <- range(bounds$north, bounds$south) 
    lngRng <- range(bounds$east, bounds$west) 

    subset(zip_coord, 
      lat >= latRng[1] & lat <= latRng[2] & 
      long >= lngRng[1] & long <= lngRng[2], select = ZIP) 
    }) 


    output$inBoundsZIPs <- renderTable({ 
    zipsInBounds() 
    }) 


}) 

shinyApp(ui, server) 

EDIT:

私は後方中心点のための私の経度と緯度の定義を持っていたが判明しました。代わりに

center <- c(mean(bounds$north, bounds$south), mean(bounds$east, bounds$west)) 

で、それは次のようになります。

center <- c(mean(bounds$east, bounds$west), mean(bounds$north, bounds$south))

ジップコードセレクタ機能は結局正しかった:私のセンターの定義が誤って別の半球に置かれたことを考えると、それに最も近い郵便番号は常にでした同じ。

決勝、および作業バージョンは次のとおりです。

# List of ZIP code centroids as X/Y coordinates 
zip_coord <- read.csv('https://www.dropbox.com/s/lz9gmrz5skvef53/zip_coord.csv?dl=1') 

# Default view location 
lat <- 42.361145 
lng <- -71.057083 
zoom <- 11 



ui <- shinyUI(fluidPage(fluidRow(
    column(
    7, 
    offset = 1, 
    leafletOutput("map", height = "700")), 
    column(
    3, 
    h5("This doesn't work: It always shows the same ZIP:"), 
    tableOutput("centerZip"), 
    br(), 
    h5("This works: the ZIPs change as you move the map around:"), 
    tableOutput("inBoundsZIPs") 
) 
))) 


server <- (function(input, output, session) { 

    output$map <- renderLeaflet({ 

    leaflet() %>% 
     addProviderTiles("Stamen.TonerLite", group = "Stamen.TonerLite") %>% 
     setView(lat = lat, 
       lng = lng, 
       zoom = zoom) 
    }) 


    # A reactive expression that returns a single zip code, the one closest to the center 
    # of the current map view 
    # NOW THIS WORKS TOO! 

    centeredZip <- reactive({ 
    if (is.null(input$map_bounds)) 
     return(NULL) 
    bounds <- input$map_bounds 
    center <- c(mean(bounds$east, bounds$west), 
       mean(bounds$north, bounds$south) 
       ) 

    nearest.zip <- zip_coord[which.min(colSums((t(zip_coord[-1]) - center)^2)),1] 
    # Pick out the point 
    subset(zip_coord, ZIP == nearest.zip) 

    }) 

    output$centerZip <- renderTable({ 
    centeredZip() 
    }) 

    # A reactive expression that returns the set of zips that are 
    # within the current view bounds 
    # THIS WORKS AS EXPECTED 

    zipsInBounds <- reactive({ 
    if (is.null(input$map_bounds)) 
     return(zip_coord[FALSE,]) 
    bounds <- input$map_bounds 
    latRng <- range(bounds$north, bounds$south) 
    lngRng <- range(bounds$east, bounds$west) 

    subset(zip_coord, 
      lat >= latRng[1] & lat <= latRng[2] & 
      long >= lngRng[1] & long <= lngRng[2], select = ZIP) 
    }) 


    output$inBoundsZIPs <- renderTable({ 
    zipsInBounds() 
    }) 


}) 

shinyApp(ui, server) 

答えて

0

私は後方中心点のための私の経度と緯度の定義を持っていたが判明してみてください。 center <- c(mean(bounds$north, bounds$south), mean(bounds$east, bounds$west)) の代わりに、 center <- c(mean(bounds$east, bounds$west), mean(bounds$north, bounds$south))にする必要があります。 郵便番号セレクター機能は、結局正しいものでした。私のセンター定義が間違って別の半球に配置された場合、それに最も近い郵便番号は常に同じでした。

+0

私の目標は毎回トップテーブルをレンダリングすることでしたあなたが探していた解決策 –

+0

私はそれを取得し、迅速な答えを感謝します。私が探していた解決策に関して、それはタイトルで明白でした(「地図の中心に最も近いポイントを選択する」) – HAVB

1

私は問題を発見した、この

library(shiny) 
library(leaflet) 

# List of ZIP code centroids as X/Y coordinates 
zip_coord <- read.csv('http://www.dropbox.com/s/lz9gmrz5skvef53/zip_coord.csv?dl=1') 

# Default view location 
lat <- 42.361145 
lng <- -71.057083 
zoom <- 11 

ui <- shinyUI(fluidPage(fluidRow(
    column(
    7, 
    offset = 1, 
    leafletOutput("map", height = "700")), 
    column(
    3, 
    h5("This doesn't work: It always shows the same ZIP:"), 
    tableOutput("centerZip"), 
    br(), 
    h5("This works: the ZIPs change as you move the map around:"), 
    tableOutput("inBoundsZIPs") 
) 
))) 


server <- (function(input, output, session) { 

    output$map <- renderLeaflet({ 

    leaflet() %>% 
     addProviderTiles("Stamen.TonerLite", group = "Stamen.TonerLite") %>% 
     setView(lat = lat, 
       lng = lng, 
       zoom = zoom) 
    }) 


    # A reactive expression that returns a single zip code, the one closest to the center 
    # of the current map view 
    # THIS DOES NOT WORK AS EXPECTED 

    centeredZip <- eventReactive(input$map_bounds,{ 
    if (is.null(input$map_bounds)) 
     return(NULL) 
    bounds <- input$map_bounds 
    center <- c(mean(bounds$north, bounds$south),mean(bounds$east, bounds$west)) 
    #center <- c(42.65214,-71.43929) 
    nearest.zip <- zip_coord[which.min(colSums(t(zip_coord[-1]) - center)^2),1]  
    # Pick out the point 
    subset(zip_coord, ZIP == nearest.zip) 
    }) 

    output$centerZip <- renderTable({ 
    centeredZip() 
    }) 

    # A reactive expression that returns the set of zips that are 
    # within the current view bounds 
    # THIS WORKS AS EXPECTED 

    zipsInBounds <- reactive({ 
    if (is.null(input$map_bounds)) 
     return(zip_coord[FALSE,]) 
    bounds <- input$map_bounds 
    latRng <- range(bounds$north, bounds$south) 
    lngRng <- range(bounds$east, bounds$west) 

    subset(zip_coord, 
      lat >= latRng[1] & lat <= latRng[2] & 
      long >= lngRng[1] & long <= lngRng[2], select = ZIP) 
    }) 


    output$inBoundsZIPs <- renderTable({ 
    zipsInBounds() 
    }) 


}) 

shinyApp(ui, server) 
+1

それでした。代わり 'zip_coordの [which.min(colSums((T(zip_coord [-1]) - 中心)^ 2))、1]' 私は 'zip_coord [which.min(colSums(Tを(必要 ()の余分なセットが私のコードをねじ込んでいた – HAVB

+0

何が起こっていたのか分かりました。 –

+0

もっと慎重なテストの後、私は実現しましたあなたのソリューションは実際にマップセンターに最も近い郵便番号を表示していません - 問題は郵便番号の行選択ではなく、中心点定義にありました – HAVB

関連する問題