게시된 주소를 지도에 반영하는 Rails 앱 만들기

Rails에서 사용자가 게시한 주소를 지도에 표시하는 앱을 만들었습니다.
극히 간단한 것이 되기 때문에 흠뻑.

애플리케이션 움직임


  • 사용자가 양식에서 주소를 게시
  • 주소를 위도 경도로 변환
  • 변환한 이동 경도로부터, 화면상의 맵에 마커를 반영시킨다.

  • 느낌입니다.

    준비



    달리기로 써 가기 때문에, 최초의 순서는 생략합니다.
    어쨌든,rails new 가 되고 있는 상태로부터 시작합니다.

    Gemfile에 추가



    Gemfile에 다음을 추가하고 bundle install을 실행합니다.
    # map表示を簡易化する
    gem 'leaflet-rails'
    # map上のマーカー周りをゴニョゴニョする
    gem 'leaflet-markercluster-rails'
    # 住所を緯度経度に変換する
    gem 'geocoder'
    

    설정 파일 추가



    config/initializers에 다음 파일 추가
    Leaflet.tile_layer = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    Leaflet.attribution = 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>'
    Leaflet.max_zoom = 18
    

    특히 어려운 설정이 아니라 보시다시피
    tile_layer를 다시 작성하면 OpenStreetMap뿐만 아니라 google map도 사용할 수 있습니다.

    scaffold로 사사토와 포스트 앱 제작



    Rails의 마법과 Scaffold에서 쉽게 사용자 게시 앱을 만듭니다.
    rails g scaffold maps name address comment:text lonlat
    

    각각
  • name : 주소를 게시 한 사용자의 이름 (없음).
  • address : 게시 된 주소
  • comment : 무엇인가의 코멘트
  • lonlat : 게시 된 주소를 (내부적으로) 위도 및 경도로 변환하고 저장합니다.

    입니다.

    위도 경도(lonlat)는 사용자가 입력하고 싶지 않으므로 _form.html.erb에서 해당 부분을 삭제해 둡니다.

    마지막으로 rails db:migrate 도 실행.

    leaflet에서 지도 보기



    이번에는 "Open Street Map"을 사용합니다.

    leaflet을 사용하기 위한 준비



    먼저 leaflet을 사용하기 때문에 application.js와 application.css에 다음을 추가합니다.

    application.js
    //= require leaflet
    //= require leaflet.markercluster
    

    application.css
     *= require leaflet
     *= require leaflet.markercluster
     *= require leaflet.markercluster.default
     */
    

    적당한 마커용 이미지를 준비



    이번은, 대단히 "marker.png"라는 이미지를/Public에 추가했다고 하는 것으로 진행합니다.

    leaflet을 사용하여 지도 표시



    maps/index에 다음 코드를 추가합니다.
    
    (省略)
    <div id="map" style="height: 500px; width: 500px;"></div>
    <%=
      map(:center => {
          :latlng => [36, 140],
          :zoom => 4,
      })
    %>
    <script>
      // rubyから渡された住所配列をjsの変数に格納
      var maps = <%= @maps.to_json.html_safe %>;
    
      for(var hash_count = 0; hash_count < maps.length; hash_count++){
        // 緯度経度とコメントを取り出しマーカー化
        L.marker(maps[hash_count].lonlat.split(','), {icon: L.icon({iconUrl: "/marker.png"})},)
          .bindPopup(maps[hash_count].comment)
          .addTo(map);
      }
    </script>
    

    스크립트 태그는 여기에 쓰는 방법이 똑똑하고 좋습니다.
    
      <% @maps.each do |map| %>
        L.marker("<%= map.lonlat %>".split(','), {icon: L.icon({iconUrl: "/cycle24.png"})},)
        .bindPopup("<%= map.comment %>")
        .addTo(map);
      <% end %>
    
    

    게시된 주소를 위도 경도로 변환



    사용자가 주소를 입력하고 저장 (또는 업데이트) 할 때 주소를 위도 경도로 변환하고 lonlat 열에 저장하는 메커니즘을 만듭니다.
    class Map < ApplicationRecord
        before_save :update_lonlat
    
        def update_lonlat
            lonlat = address_to_lonlat(read_attribute(:address))
            write_attribute(:lonlat, lonlat)
        end
    
        # 住所を保存用経緯度に変換
        def address_to_lonlat(address)
          result = Geocoder.search(address)
          lonlat = result.first.coordinates
          return lonlat.join(',')
        end
    end
    

    이것만으로, 주소(address) 컬럼을 보존, 갱신했을 때에 위도 경도(lonlat) 컬럼도 갱신해 줍니다.

    완성



    위의 절차로 아마 완성해야 할 것입니다.


    잠자리에 들고 쓰고 있기 때문에 상당히 달리기 시작했지만 읽어 주셔서 감사합니다.
  • 좋은 웹페이지 즐겨찾기