Ich zeichne eine große Lat-lon NetCDF raster
über eine R leaflet
Karte mit shinydashboard
. Wenn ich auf die Karte klicke, erscheint ein Popup-Fenster, in dem Zeile, Spalte, Breitengrad und Wert des angeklickten Rasterpunkts angezeigt werden. (Siehe reproduzierbaren Code unten)Identifizieren Sie die Position eines Klick auf ein Raster in Prospekt, in R
Das Problem ist, dass ich eine Verschiebung im Raster erfahre, wenn das Raster groß genug ist. Zum Beispiel habe ich hier auf einen Punkt geklickt, der einen Wert haben sollte, aber das Ergebnis ist, dass der identifizierte Punkt der obige ist.
Ich glaube, dies mit der Tatsache zu tun, dass das Raster von leaflet
verwendet wird projiziert, während die Rohdaten ich die Punkte zu identifizieren, verwenden Lat-Lon ist, da der angeklickten Punkt als Lat zurückgegeben -Lon von leaflet
. Ich kann die projizierte Datei (depth
) nicht verwenden, da ihre Einheiten in Metern und nicht in Grad angegeben sind! Selbst wenn ich versuchte, diese Meter auf Grad umzustellen, bekam ich eine Verschiebung.
Hier ist ein grundlegendes runnable Beispiel für den Code:
#Libraries
library(leaflet)
library(raster)
library(shinydashboard)
library(shiny)
#Input data
download.file("https://www.dropbox.com/s/y9ekjod2pt09rvv/test.nc?dl=0", destfile="test.nc")
inputFile = "test.nc"
inputVarName = "Depth"
lldepth <- raster(inputFile, varname=inputVarName)
lldepth[Which(lldepth<=0, cells=T)] <- NA #Set all cells <=0 to NA
ext <- extent(lldepth)
resol <- res(lldepth)
projection(lldepth) <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
#Project for leaflet
depth <- projectRasterForLeaflet(lldepth)
#Prepare UI
sbwidth=200
sidebar <- dashboardSidebar(width=sbwidth)
body <- dashboardBody(
box(#https://stackoverflow.com/questions/31278938/how-can-i-make-my-shiny-leafletoutput-have-height-100-while-inside-a-navbarpa
div(class="outer",width = NULL, solidHeader = TRUE, tags$style(type = "text/css", paste0(".outer {position: fixed; top: 50px; left: ", sbwidth, "px; right: 0; bottom: 0px; overflow: hidden; padding: 0}")),
leafletOutput("map", width = "100%", height = "100%")
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "A title"),
sidebar,
body
)
#
#Server instance
server <- function(input, output, session) {
output$map <- renderLeaflet({#Set extent
leaflet() %>%
fitBounds(ext[1], ext[3], ext[2], ext[4])
})
observe({#Observer to show Popups on click
click <- input$map_click
if (!is.null(click)) {
showpos(x=click$lng, y=click$lat)
}
})
showpos <- function(x=NULL, y=NULL) {#Show popup on clicks
#Translate Lat-Lon to cell number using the unprojected raster
#This is because the projected raster is not in degrees, we cannot use it!
cell <- cellFromXY(lldepth, c(x, y))
if (!is.na(cell)) {#If the click is inside the raster...
xy <- xyFromCell(lldepth, cell) #Get the center of the cell
x <- xy[1]
y <- xy[2]
#Get row and column, to print later
rc <- rowColFromCell(lldepth, cell)
#Get value of the given cell
val = depth[cell]
content <- paste0("X=",rc[2],
"; Y=",rc[1],
"; Lon=", round(x, 5),
"; Lat=", round(y, 5),
"; Depth=", round(val, 1), " m")
proxy <- leafletProxy("map")
#add Popup
proxy %>% clearPopups() %>% addPopups(x, y, popup = content)
#add rectangles for testing
proxy %>% clearShapes() %>% addRectangles(x-resol[1]/2, y-resol[2]/2, x+resol[1]/2, y+resol[2]/2)
}
}
#Plot the raster
leafletProxy("map") %>%
addRasterImage(depth, opacity=0.8, project=FALSE, group="Example", layerId="Example", colors=colorNumeric(terrain.colors(10), values(depth), na.color = "black"))
}
print(shinyApp(ui, server))
Wie kann ich die Punkte korrekt identifizieren, wenn das Raster groß ist?
EDIT: Ich wollte auch einige zusätzliche Links zu (möglicherweise) die zugehörige Dokumentation oder Fragen geben:
- Raster image seems to be shifted using leaflet for R
- R for leaflet redirect when clicking on raster image
- https://gis.stackexchange.com/questions/183918/is-it-possible-to-use-a-rasterclick-event-within-an-interactive-leaflet-map
- marker mouse click event in R leaflet for shiny
Ah! Ich denke, ich habe es geschafft, die Click-Daten erneut zu projizieren. Ich werde experimentieren und dann eine Antwort posten. – AF7