Prevent flyTo within a leaflet in shiny from refreshing map

I am trying to add an easyButton with a flyTo function within a shiny app.

When the user presses the button, it will fly to the current location (lat/long). I am using a reactivePoll to poll a boat instrument simulator every 5 seconds (NMEA simulator), which is where the lat/long come from. A path is also drawn by using addCircleMarkers. I want to keep this path drawn, and the flyTo button to pan and zoom to the current location without refreshing the map, i.e. removing the path that was drawn.

In my current code with the flyTo button, with every poll the map refreshes. If I remove this code, the map does not refresh, so I think how I'm using the reactive within this button is the issue, but I'm not sure why. It may be because I have a reactive inside a reactive (All_NMEA() inside of renderleaflet()). I tried moving it into an observe at the bottom, but it does not show up on the map. The code of interest in the reprex is:

addEasyButton(easyButton(
        icon = "fa-crosshairs", title = "Locate Vessel",
        onClick = JS("
             function(btn, map) {
             map.flyTo([", paste(as.numeric(All_NMEA()["lat"]) / 100), ",", paste(as.numeric(All_NMEA()["long"]) / -100), "], zoom = 10);
             }
             ")
    ))

The NMEA simulator is required to produce data that is polled, linked above.
Reproducible example:

# https://chrome.google.com/webstore/detail/nmea-simulator/dfhcgoinjchfcfnnkecjpjcnknlipcll?hl=en
# needs an NMEA simulator to generate the poll data
#

library(shiny)
library(leaflet)

connect <- function() {
	s_con <<- socketConnection("127.0.0.1", port = 55555, open = "a+")
	Sys.sleep(1)
	NMEA_poll <<- readLines(s_con, n = 18)
	close(s_con)
	return(NMEA_poll)
	
}

pollGPRMC <- function(data) {
	gps_ans <- list(rmc = NULL, rest = data)
	rxp <-
		"\\$GPRMC(,[^,]*){12}\\*[0-9,A-F]{2}"
	beg <- regexpr(rxp, data)
	if (beg == -1)
		return(gps_ans)
	end <-
		beg + attr(beg, "match.length")
	sub <-
		substr(data, beg, end - 6)
	gps_ans$rmc <-
		strsplit(sub, ",")[[1]]
	names(gps_ans$rmc) <- c(
		"id_rmc",
		"UTC",
		"status",
		"lat",
		"N/S",
		"long",
		"E/W",
		"boat speed (knots)",
		"cog (deg)",
		"date (ddmmyy)" # ddmmyy
	)
	gps_ans$rest <- substr(data, end, nchar(data))
	return(gps_ans)
}

map_data <- data.frame(lat = c(36.05, 36.25), lon = c(-132.13, -132.33))


ui <- fluidPage(

	# Application title
	titlePanel("Map"),

	mainPanel(tags$style(type = "text/css", "#map {height: calc(100vh - 80px) !important;}"),
			  leafletOutput("map"))
)


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

	All_NMEA <- shiny::reactivePoll(
		5000,
		session,
		checkFunc = Sys.time,
		valueFunc = function() {
				connect()
				
				NMEA_data <- toString(NMEA_poll)
				GPS_dat <- pollGPRMC(NMEA_data)
				
				lat_deg <- substr(GPS_dat$rmc["lat"], 1, 2)
				lat_mins <- substr(GPS_dat$rmc["lat"], 3, 9)
				lat_for_dist <- as.numeric(lat_deg) + (as.numeric(lat_mins) / 60)
				print(lat_for_dist)
				lon_deg <- substr(GPS_dat$rmc["long"], 1, 3)
				lon_mins <- substr(GPS_dat$rmc["long"], 4, 9)
				lon_for_dist <- (as.numeric(lon_deg) + (as.numeric(lon_mins) / 60))*-1
				print(lon_for_dist)

								
			NMEA_out <- c(GPS_dat$rmc)
			
			return(NMEA_out)
			
		}
	)
	
	ord <- function(data) {
		print(data)
	}
	
	observe(ord(All_NMEA()))
	
           my_map <- leafletProxy("map", session = session) 

	output$map <- renderLeaflet({
		map <- leaflet(map_data) %>%
			addProviderTiles(providers$Esri.OceanBasemap, group = "ocean basemap (default)") %>%
			addTiles(group = "Basic") %>%
			fitBounds( ~ min(lon), ~ min(lat), ~ max(lon), ~ max(lat)) %>%
			addLayersControl(
				baseGroups = c("ocean basemap (default)", "Basic"),
				options = layersControlOptions(collapsed = FALSE)) %>%
				   fitBounds( ~ min(lon), ~ min(lat), ~ max(lon), ~ max(lat)) %>%
		addEasyButton(easyButton(
			icon = "fa-crosshairs", title = "Locate Vessel",
			onClick = JS("
				 function(btn, map) {
				 map.flyTo([", paste(as.numeric(All_NMEA()["lat"]) / 100), ",", paste(as.numeric(All_NMEA()["long"]) / -100), "], zoom = 10);
				 }
				 ")
		))
	})
observe({
    map_loc <- All_NMEA()
    my_map %>% 
        addCircleMarkers(
            lng = as.numeric(map_loc["long"]) / -100,
            lat = as.numeric(map_loc["lat"]) / 100,
            radius = 1,
            fillOpacity = 1, color = "red"
        ) #%>% 
        # addEasyButton(easyButton(
        #     icon = "fa-crosshairs", title = "Locate Vessel",
        #     onClick = JS("
        #      function(btn, map) {
        #      map.flyTo([", as.numeric(map_loc["lat"]) / 100, ",", as.numeric(map_loc["long"]) / -100, "], zoom = 10);
        #      }
        #      ")
        # ))
        
    
})

}


shinyApp(ui = ui, server = server)

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.