在 ShinyApp 中单击 ggmap 不会 return 正确坐标

Clicking a ggmap in a ShinyApp does not return correct coordinates

如果我将点击事件附加到 ShinyApp 中的 ggmap,然后点击地图,我不会取回正确的坐标点。

以下应用程序绘制了一张地图,上面有一些点,并将点击事件附加到地图上。我的目标是拥有它,这样当我单击这些点时,它们的数据(在本例中为 lon/lat)应该出现在 outputId="coords" verbatimTextOutput.

app.R:

library(shiny);
library(ggmap);

# load data
points <- data.frame(lon=c(-122,-121.9,-121.8,-121.7),lat=c(37.2,37.2,37.2,37.2));
map <- get_map(location = c(lon = mean(points$lon),lat = mean(points$lat)),maptype="roadmap",scale=2, zoom =11)


ui <- fluidPage (
  plotOutput(outputId="mapOut",
             width="100%", height="500px",
             click = "plot_click"
  ),
  verbatimTextOutput(outputId="info"),
  verbatimTextOutput(outputId="coords")

)


server <- function(input,output) {

  output$mapOut <- renderPlot({
     mapPoints <-  ggmap(map) + geom_point(aes(x = lon, y = lat),size=8,colour="black", data=points);;
     mapPoints
  })

  output$info <- renderPrint({
    ptClicked <- nearPoints(points, coordinfo = input$plot_click, threshold = 10, maxpoints = 1, xvar="lon", yvar="lat");
    data.frame(lon=ptClicked$lon,lat=ptClicked$lat);

  })

  output$coords <- renderText({
    paste0("x=", input$plot_click$x, "\ny=", input$plot_click$y)
  })
}

shinyApp(server = server, ui = ui)

当我 运行 这个应用程序时,点显示在正确的位置。如果我直接点击一个点, nearPoints() in output$info <- ... 不能正确识别该点。这是因为点击返回的坐标是错误的。 (正如您从 "coords" 逐字文本输出中看到的那样。)

如果我点击该点的右侧,从而使返回的点击坐标在数据意义上为 "on the point",则返回该点。

问题类似于getting correct click coords with ggplot map in shiny,除了在[0,1]中坐标作为数字返回;在我的例子中,坐标看起来像真正的坐标,但有点不对……从那个问题我还注意到,即使在使用 lon <- 400*x - 200 和 lat <- 200*y - 100 重新缩放之后,坐标还是仍然很遥远(例如(lon,lat)=(0,0)似乎映射到(8.9,5.4)左右)。所以ggplot在用来作图的时候好像也面临同样的问题

有没有办法让点击 ggmap/ggplot 产生正确的坐标?这可能与预测有关。

如果不是,是否有其他方法可以解决问题以便正确点击这些点? (例如,一种解决方法可能是以某种方式捕获绘制点的 "as far as clicking is concerned" (x,y) 位置,存储它们,并使用它们代替 lon/lat 用于 nearPoints() 目的...)。

ggmap() 默认使用 ggplot2 中的 coord_map() 投影,这会扭曲坐标。要在 Shiny 中获得正确的点击坐标,您需要将其转回笛卡尔坐标。这可以简单地通过添加 coord_cartesian() 来完成。由于 coord_map() 已被剥离,输出图的纵横比可以是任意的。所以你需要改变 plotOutput() 中的宽度和高度,使地图仍然是一个漂亮的地图。

下面是经过上述小修改的代码。它会产生正确的点击和漂亮的地图。

library(shiny);
library(ggmap);

# load data
points <- data.frame(lon=c(-122,-121.9,-121.8,-121.7),lat=c(37.2,37.2,37.2,37.2))
map <- get_map(location = c(lon = mean(points$lon),lat = mean(points$lat)),
               maptype="roadmap",scale=2, zoom =11)


ui <- fluidPage (
    plotOutput(outputId="mapOut",
               ##########################################################
               # force the ratio of the width and height so that the map
               # appears as square
               width=530, height=500,  
               click = "plot_click"
    ),
    verbatimTextOutput(outputId="info"),
    verbatimTextOutput(outputId="coords")

)


server <- function(input,output) {

    output$mapOut <- renderPlot({
        mapPoints <-  ggmap(map, extent = "normal") + 
            geom_point(aes(x = lon, y = lat),size=8,colour="black", data=points)
        #########################################################
        # add coord_cartesian() to strip coord_map() from ggmap()
        mapPoints + coord_cartesian()
    })

    output$info <- renderPrint({
        ptClicked <- nearPoints(points, coordinfo = input$plot_click, 
                                threshold = 10, maxpoints = 1, 
                                xvar="lon", yvar="lat");
        data.frame(lon=ptClicked$lon,lat=ptClicked$lat);

    })

    output$coords <- renderText({
        paste0("x=", input$plot_click$x, "\ny=", input$plot_click$y)
    })
}

shinyApp(server = server, ui = ui)