수색…


레이아웃 헤더에 google maps javascript 태그를 추가하십시오.

Google지도가 터보 링크로 제대로 작동하도록하려면 레이아웃에 헤더를 포함하는 대신 javascript 태그를 레이아웃 헤더에 직접 추가하십시오.

# app/views/layouts/my_layout.html.haml
!!!
%html{:lang => 'en'}
  %head
    - # ...
    = google_maps_api_script_tag

google_maps_api_script_tag 는 도우미로 정의하는 것이 가장 좋습니다.

# app/helpers/google_maps_helper.rb
module GoogleMapsHelper
  def google_maps_api_script_tag
    javascript_include_tag google_maps_api_source
  end

  def google_maps_api_source
    "https://maps.googleapis.com/maps/api/js?key=#{google_maps_api_key}"
  end

  def google_maps_api_key
    Rails.application.secrets.google_maps_api_key
  end
end

Google에 애플리케이션을 등록하고 Google API 콘솔 에서 API 키를 얻을 수 있습니다. Google은 짧은 지도 자바 API API에 대한 API를 API를 요청하는 방법이 있습니다.

api 키는 secrets.yml 파일에 저장됩니다.

# config/secrets.yml
development:
  google_maps_api_key: '...'
  # ...
production:
  google_maps_api_key: '...'
  # ...

.gitignore 파일에 config/secrets.yml 을 추가하는 것을 잊지 말고 api 키를 저장소에 적용하지 마십시오.

모델 지오 코딩

사용자 및 / 또는 그룹에 프로필이 있고 Google지도에 주소 프로필 필드를 표시하려고한다고 가정합니다.

# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
  # Attributes: 
  # label, e.g. "Work address"
  # value, e.g. "Willy-Brandt-Straße 1\n10557 Berlin"
end

주소를 지오 코딩하는 훌륭한 방법, 즉 longitudelatitude 제공하는 것은 지오 코더 젬 입니다.

Geocoder를 Gemfile 추가하고 bundle 을 실행하여 설치하십시오.

# Gemfile
gem 'geocoder', '~> 1.3'

latitudelongitude 에 대한 데이터베이스 열을 추가하여 데이터베이스에 위치를 저장하십시오. 이는 위치가 필요할 때마다 지오 코딩 서비스를 쿼리하는 것보다 효율적입니다. 그것은 더 빠르며 쿼리 제한을 그렇게 빨리 치지 않습니다.

➜ bin/rails generate migration add_latitude_and_longitude_to_profile_fields \
    latitude:float longitude:float
➜ bin/rails db:migrate  # Rails 5, or:
➜ rake db:migrate       # Rails 3, 4

모델에 지오 코딩 메커니즘을 추가하십시오. 이 예에서 주소 문자열은 value 속성에 저장됩니다. 레코드가 변경되고 값만있는 경우 수행 할 지오 코딩을 구성하십시오.

# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
  geocoded_by :value
  after_validation :geocode, if: ->(address_field){ 
    address_field.value.present? and address_field.value_changed? 
  }

end

기본적으로 지오 코더는 Google을 검색 서비스로 사용합니다. 거리 계산이나 근접 검색과 같은 흥미로운 기능이 많이 있습니다. 자세한 정보는 지오 코더 README를 참조하십시오 .

프로필보기에서 Google지도의 주소 표시

프로필보기에서 사용자 또는 그룹의 프로필 입력란을 목록에 표시하고 Google지도의 주소 입력란을 표시하십시오.

- # app/views/profiles/show.html.haml
%h1 Contact Information
.profile_fields
  = render @profile_fields
.google_map{data: address_fields: @address_fields.to_json }

적절한 @profile_fields@address_fields 가 컨트롤러에 설정됩니다.

# app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
  def show
    # ...
    @profile_fields = @user_or_group.profile_fields
    @address_fields = @profile_fields.where(type: 'ProfileFields::Address')
  end
end

지도를 초기화하고, 마커를 배치하고, 확대 / 축소 및 기타지도 설정을 자바 스크립트로 설정하십시오.

프로필보기의 예

지도에서 자바 스크립트로 마커 설정

지도가 될 .google_map div가 있으며 data 속성으로 표시 자로 표시 할 주소 입력란이 있다고 가정 해 .google_map .

예 :

<!-- http://localhost:3000/profiles/123 -->
<div class="google_map" data-address-fields="[
  {label: 'Work address', value: 'Willy-Brandt-Straße 1\n10557 Berlin', 
  position: {lng: ..., lat: ...}},
  ...
]"></div>

turbolinks 이벤트를 직접 관리하지 않고 turbolinks로 $(document).ready 이벤트를 사용하려면 jquery.turbolinks gem을 사용하십시오.

나중에 필터링이나 정보 창과 같이 맵을 사용하여 다른 작업을 수행하려는 경우 커피 스크립트 클래스로 지도를 관리하는 것이 편리합니다.

# app/assets/javascripts/google_maps.js.coffee
window.App = {} unless App?
class App.GoogleMap
  constructor: (map_div)->
    # TODO: initialize the map
    # TODO: set the markers

기본적으로 네임 스페이스가있는 여러 가지 커피 스크립트 파일을 사용할 때 모든 커피 스크립트 파일에서 공유하는 전역 App 네임 스페이스를 정의하는 것이 편리합니다.

그런 다음 여러 개의 (가능한 경우) .google_map div를 App.GoogleMap 하여 각각에 대해 App.GoogleMap 클래스의 인스턴스 하나를 만듭니다.

# app/assets/javascripts/google_maps.js.coffee
# ...
$(document).ready ->
  App.google_maps = []
  $('.google_map').each ->
    map_div = $(this)
    map = new App.GoogleMap map_div
    App.google_maps.push map

커피 스크립트 클래스를 사용하여지도를 초기화하십시오.

App.GoogleMap 커피 스크립트 클래스 를 제공하면 Google지도를 다음과 같이 초기화 할 수 있습니다.

# app/assets/javascripts/google_maps.js.coffee
# ...
class App.GoogleMap
  map_div: {}
  map: {}
  
  constructor: (map_div)->
    @map_div = map_div
    @init_map()
    @reference_the_map_as_data_attribute

  # To access the GoogleMap object or the map object itself
  # later via the DOM, for example 
  # 
  #     $('.google_map').data('GoogleMap')
  #
  # store references as data attribute of the map_div.
  #
  reference_the_map_as_data_attribute: ->
    @map_div.data 'GoogleMap', this
    @map_div.data 'map', @map

  init_map: ->
    @map = new google.maps.Map(@dom_element, @map_configuration) if google?

  # `@map_div` is the jquery object. But google maps needs
  # the real DOM element.
  #
  dom_element: ->
    @map_div.get(0)

  map_configuration: -> {
    scrollWheel: true
  }

가능한 map_configuration 옵션에 대해 자세히 알아 보려면 google의 MapOptions 설명서컨트롤 요소 추가 가이드를 참조하십시오 .

참고로 google.maps.Map 클래스 는 여기에 광범위하게 설명되어 있습니다 .

커피 스크립트 클래스를 사용하여지도 표시 자 초기화

App.GoogleMap 커피 스크립트 클래스 와 마커 정보가 .google_map div의 data-address-fields 속성에 저장되어 .google_map 과 같이지도 아이콘을지도에서 초기화 할 수 있습니다.

# app/assets/javascripts/google_maps.js.coffee
# ...
class App.GoogleMap
  # ...
  markers: []

  constructor: (map_div)->
    # ...
    @init_markers()

  address_fields: ->
    @map_div.data('address-fields')

  init_markers: ->
    self = this  # to reference the instance as `self` when `this` is redefined.
    self.markers = []
    for address_field in self.address_fields()
      marker = new google.maps.Marker {
        map: self.map,
        position: {
          lng: address_field.longitude,
          lat: address_field.latitude
        },
        # # or, if `position` is defined in `ProfileFields::Address#as_json`:
        # position: address_field.position,
        title: address_field.value
      }
      self.markers.push marker

마커 옵션에 대해 자세히 알아 보려면 Google의 MarkerOptions 설명서마커에 대한 가이드를 참조하십시오 .

커피 스크립트 클래스를 사용하여지도 자동 확대 / 축소

제공 App.GoogleMap 커피 스크립트 클래스google.maps.Map 저장 @mapgoogle.maps.Marker 의 저장 @markers , 즉 자동 확대, 모든 마커는 다음과 같이 볼 수 있도록 조정할 수지도 :지도에서 이렇게 :

# app/assets/javascripts/google_maps.js.coffee
# ...
class App.GoogleMap
  # ...
  bounds: {}

  constructor: (map_div)->
    # ...
    @auto_zoom()

  auto_zoom: ->
    @init_bounds()
    # TODO: Maybe, adjust the zoom to have a maximum or 
    # minimum zoom level, here.

  init_bounds: ->
    @bounds = new google.maps.LatLngBounds()
    for marker in @markers
      @bounds.extend marker.position
    @map.fitBounds @bounds

경계에 대해 자세히 알아 보려면 google의 LatLngBounds 문서를 참조하십시오 .

모델 속성을 json으로 노출

Google지도에 주소 프로필 입력란을 표시 자로 표시하려면 주소 입력란 개체를 json 개체로 javascript에 전달해야합니다.

정규 데이터베이스 속성

ApplicationRecord 객체에서 to_json 을 호출하면 데이터베이스 속성이 자동으로 노출됩니다.

label , value , longitudelatitude 속성을 가진 ProfileFields::Address 모델이 주어지면 address_field.as_jsonHash (예 : 표현)

address_field.as_json  # =>
  {label: "Work address", value: "Willy-Brandt-Straße 1\n10557 Berlin",
    longitude: ..., latitude: ...}

to_json 의해 json 문자열로 변환됩니다.

address_field.to_json  # =>
  "{\"label\":\"Work address\",\"value\":\"Willy-Brandt-Straße 1\\n
    10557 Berlin\",\"longitude\":...,\"latitude\":...}"

예를 들어,지도 마커에 대한 도구 설명을 표시하는 것과 같이 나중에 자바 스크립트에서 labelvalue 을 사용할 수 있기 때문에 유용합니다.

기타 속성

as_json 메소드를 대체하여 다른 가상 속성을 노출 할 수 있습니다.

예를 들어 title 속성을 노출하려면 병합 된 as_json 해시에 포함 시키십시오.

# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
  # ...

  # For example: "John Doe, Work address"
  def title
    "#{self.parent.name}, #{self.label}"
  end

  def as_json
    super.merge {
      title: self.title
    }
  end
end

위의 예에서는 super 를 사용하여 원래 as_json 메서드를 호출합니다.이 메서드는 개체의 원래 특성 해시를 반환하고 필요한 위치 해시와 병합합니다.

as_jsonto_json 의 차이점을 이해하려면 as_json 블로그 게시물을 살펴보십시오 .

위치

마커를 렌더링하기 위해 기본적으로 Google지도 api에는 경도와 위도가 각각 lnglat 로 저장된 position 해시가 필요합니다.

이 위치 해시는 주소 필드의 json 표현을 정의 할 때 javascript, later 또는 here에서 만들 수 있습니다.

position 를 주소 필드의 json 속성으로 제공하려면 모델에서 as_json 메소드를 무시하십시오.

# app/models/profile_fields/address.rb
class ProfileFields::Address < ProfileFields::Base
  # ...

  def as_json
    super.merge {
      # ...
      position: {
        lng: self.longitude,
        lat: self.latitude
      }
    }
  end
end


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow