R Блестящая карта поиска поля ввода - PullRequest
0 голосов
/ 17 ноября 2018

В картах Google поле ввода поиска автоматически заполняет адреса при вводе пользователем.Есть ли способ сделать это в R Shiny с доступом к значению автозаполнения для использования с пакетом сопоставления?

enter image description here

Существует JavaScriptметод здесь .Я пытался использовать этот метод в R Shiny в коде ниже.SymbolixAU указал на использование google_map( search_box = TRUE ), что является простым решением.К сожалению, это не работает в моем коде, а также потому, что я хотел бы, чтобы окно поиска было отделено от карты.

В приведенной ниже попытке есть текстовый ввод my_address, текстовый вывод copy_of_address и googleway.map my_map в указанном порядке на странице.

Предполагаемое поведение для пользователя - вводить текст в текстовый ввод my_address, иметь автозаполнение с адресом (это работает), адрес будет скопированв текстовый вывод copy_of_address (это показывает только то, что было напечатано, а не автозаполненную версию) и, наконец, карта должна быть центрирована по этому адресу.

The shiny app

Убедитесь, что в поле ввода есть адрес автозаполнения, однако в копии адреса и карты используется только текст, введенный пользователем.

В приведенном ниже коде замените 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)

1 Ответ

0 голосов
/ 24 февраля 2019

Мне было нелегко разобраться, но я думаю, что у меня есть разумное решение. В конечном итоге все сводилось к копированию и вставке примера из Google очень очень внимательно, к прочтению о том, как отправлять сообщения из Javascript в Shiny, собирать идеи и получать удачу в 200-й попытке ...

Чтобы дать кредит, где он должен:

Ссылка Google: https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete

RStudio's Link: 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

...