R Блестящая карта поиска поля ввода
В Google Maps, поле ввода поиска автоматически заполняет адреса по мере ввода пользователем. Есть ли способ сделать это в R Shiny с доступом к значению автозаполнения для использования с пакетом сопоставления?
Здесь есть метод javascript. Я пытался использовать этот метод в R Shiny в коде ниже. SymbolixAU указал, используя google_map( search_box = TRUE )
что является простым решением. К сожалению, это не работает в моем коде, а также потому, что я хотел бы, чтобы окно поиска было отделено от карты.
Попытка ниже имеет текстовый ввод my_address
текстовый вывод copy_of_address
и карта Googleway my_map
в таком порядке на странице.
Предполагаемое поведение для пользователя, чтобы ввести текст в текстовый ввод my_address
, если автозаполнение с адресом (это работает), адрес будет скопирован в текстовый вывод copy_of_address
(это показывает только то, что было напечатано, а не версию с автозаполнением) и, наконец, карта должна быть центрирована по этому адресу.
Обратите внимание, что поле ввода имеет адрес автозаполнения, однако копия адреса и карты использует только пользовательский текст ввода.
В приведенном ниже коде замените MyKey
с вашим ключом API Google (иногда работает пустая строка).
library(shiny)
library(googleway)
key <- "MyKey"
set_key(key = key)
google_keys()
ui <- shiny::basicPage(
div(
textInput(inputId = "my_address", label = "")
,textOutput(outputId = "copy_of_address")
,HTML(paste0("
<script>
function initAutocomplete() {
new google.maps.places.Autocomplete(
(document.getElementById('my_address')),
{types: ['geocode']}
);
}
</script>
<script src='https://maps.googleapis.com/maps/api/js?key=", key,"&libraries=places&callback=initAutocomplete'
async defer></script>
"))
,google_mapOutput(outputId = "my_map")
)
)
server <- function(input, output) {
my_address <- reactive({
input$my_address
})
output$copy_of_address <- renderText({
my_address()
})
output$my_map <- renderGoogle_map({
my_address <- my_address()
validate(
need(my_address, "Address not available")
)
df <- google_geocode(address = my_address)
my_coords <- geocode_coordinates(df)
my_coords <- c(my_coords$lat[1], my_coords$lng[1])
google_map(
location = my_coords,
zoom = 12,
map_type_control = FALSE,
zoom_control = FALSE,
street_view_control = FALSE
)
})
}
shinyApp(ui, server)
0 ответов
Мне было нелегко понять это, но я думаю, что у меня есть разумное решение. В конечном итоге все сводилось к тому, что мы очень тщательно копировали и вставляли пример из Google, читали о том, как отправлять сообщения из Javascript в Shiny, собирать идеи и получать удачу в 200-й попытке...
Чтобы дать кредит там, где он должен:
Ссылка Google: https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete
Ссылка RStudio: https://shiny.rstudio.com/articles/js-send-message.html
Мое потенциальное решение:
library(shiny)
library(googleway)
key <- "MyKey"
set_key(key = key)
#google_keys()
ui <- shiny::basicPage(
div(
textInput(inputId = "my_address", label = "Type An Address")
,textOutput(outputId = "full_address")
,HTML(paste0(" <script>
function initAutocomplete() {
var autocomplete = new google.maps.places.Autocomplete(document.getElementById('my_address'),{types: ['geocode']});
autocomplete.setFields(['address_components', 'formatted_address', 'geometry', 'icon', 'name']);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
var addressPretty = place.formatted_address;
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || ''),
(place.address_components[3] && place.address_components[3].short_name || ''),
(place.address_components[4] && place.address_components[4].short_name || ''),
(place.address_components[5] && place.address_components[5].short_name || ''),
(place.address_components[6] && place.address_components[6].short_name || ''),
(place.address_components[7] && place.address_components[7].short_name || '')
].join(' ');
}
var address_number =''
address_number = [(place.address_components[0] && place.address_components[0].short_name || '')]
var coords = place.geometry.location;
//console.log(address);
Shiny.onInputChange('jsValue', address);
Shiny.onInputChange('jsValueAddressNumber', address_number);
Shiny.onInputChange('jsValuePretty', addressPretty);
Shiny.onInputChange('jsValueCoords', coords);});}
</script>
<script src='https://maps.googleapis.com/maps/api/js?key=", key,"&libraries=places&callback=initAutocomplete' async defer></script>"))
,google_mapOutput(outputId = "my_map")
)
)
server <- function(input, output) {
my_address <- reactive({
if(!is.null(input$jsValueAddressNumber)){
if(length(grep(pattern = input$jsValueAddressNumber, x = input$jsValuePretty ))==0){
final_address<- c(input$jsValueAddressNumber, input$jsValuePretty)
} else{
final_address<- input$jsValuePretty
}
final_address
}
})
output$full_address <- renderText({
if(!is.null(my_address())){
my_address()
}
})
output$my_map <- renderGoogle_map({
my_address <- my_address()
shiny::validate(
need(my_address, "Address not available")
)
not_a_df <- google_geocode(address = my_address)
my_coords <- geocode_coordinates(not_a_df)
my_coords <- c(my_coords$lat[1], my_coords$lng[1])
google_map(
location = my_coords,
zoom = 12,
map_type_control = FALSE,
zoom_control = FALSE,
street_view_control = FALSE
)
})
}
shinyApp(ui, server)
Надеюсь, это поможет. Ура! --nate