【问题标题】:Get Latitude and Longitude in Ruby On Rails在 Ruby On Rails 中获取纬度和经度
【发布时间】:2019-07-12 22:18:11
【问题描述】:

在 JavaScript 中,我可以轻松获取当前的纬度和经度坐标,我正在尝试在 Ruby On Rails 中实现这一点

在 Javascript 中,我可以使用以下代码来获取我当前的纬度和经度。

var x = document.getElementById("demo");

    function getLocation() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition);
  } else { 
    x.innerHTML = "Geolocation is not supported by this browser.";
  }
}

function showPosition(position) {
  x.innerHTML = "Latitude: " + position.coords.latitude + 
  "<br>Longitude: " + position.coords.longitude;
}

在 Rails 中,我可以使用以下方法获取我当前的 IP 地址

Net::HTTP.get(URI.parse('http://checkip.amazonaws.com/')).squish

但是,我无法将其转换为纬度和经度,

Javascript 方法要求用户允许使用他们当前的位置,这对于我所面临的场景来说是理想的。我意识到有一些宝石可以解决这个问题,但是我需要它在 javascript 方法所做的本地主机上工作。

【问题讨论】:

    标签: javascript ruby-on-rails ruby geolocation ruby-on-rails-6


    【解决方案1】:

    geocoder gem 不能与 localhost 一起使用。如果在生产中使用它,它只能给出近似的结果。

    前端向后端发送ajax请求可以得到更精确的结果。

    示例:

    <!-- application.html.erb -->
    <!DOCTYPE html>
    <html>
      <head>
        <%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js' %>
        <%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.0/noty.js' %>
        <%= stylesheet_link_tag 'https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.0/noty.min.css' %>
    
        <script>
          // It's bad to write inline javascript. To be moved into separate .js file
          $(function() {
            Noty.overrideDefaults({ theme: 'relax', layout: 'topCenter' });
    
            $('.getLocation').click(function(e) {
              event.preventDefault();
    
              if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(function(position) {
                  $('.latInput').val(position.coords.latitude);
                  $('.longInput').val(position.coords.longitude);
    
                  new Noty({
                    text: "Got location",
                    type: "success"
                  }).show();
                }, function(position) {
                  new Noty({
                    text: "Could not get location",
                    type: "error"
                  }).show();
                });
              } else {
                new Noty({
                  text: "Geolocation is not supported by this browser.",
                  type: "error"
                }).show();
              }
            });
    
            $('.resetLocation').click(function(e) {
              event.preventDefault();
    
              $('.latInput').val('');
              $('.longInput').val('');
            });
    
            $('.submitAjax').click(function(e) {
              event.preventDefault();
    
              var lat = $('.latInput').val();
              var long = $('.longInput').val();
              if (lat && long) {
                $.ajax({
                  url: "/",
                  data: {
                    lat: lat,
                    long: long
                  }
                }).done(function() {
                  new Noty({
                    text: "Data was successfully submitted to server via AJAX",
                    type: "success"
                  }).show();
                }).fail(function() {
                  new Noty({
                    text: "Couldn't send data",
                    type: "error"
                  }).show();
                });
              } else {
                new Noty({
                  text: "Click on 'Get Location' button first",
                  type: "error"
                }).show();
              }
            });
    
            $('.clearAndSubmit').click(function(e) {
              $('.latInput').val('');
              $('.longInput').val('');
            });
          });
        </script>
      </head>
      <body>
        <%
          ip = request.remote_ip
          ip = '8.8.8.8' if ip.in?(["::1", "127.0.0.1"])
        %>
        Geocoder.search(ip):
        <br />
        <textarea cols="50" rows="10"><%= Geocoder.search(ip) %></textarea>
        <hr />
        <% if params[:lat].present? && params[:long].present? %>
          Form was submitted:
          <br />
          Lat: <%= params[:lat] %>
          <br />
          Long: <%= params[:lat] %>
        <% else %>
          Form was not submitted
        <% end %>
        <br />
        <br />
        <%= form_tag '/', method: :get do |f| %>
          <button class="getLocation">Get Location</button>
          &nbsp;
          <button class="resetLocation">Reset Location</button>
          <br />
          <br />
          <%= label_tag :lat, 'Lat:' %>
          <%= text_field_tag :lat, params[:lat], class: 'latInput' %>      
          <%= label_tag :long, 'Long:' %>
          <%= text_field_tag :long, params[:long], class: 'longInput' %>      
          <br />
          <br />
          <button class="submitAjax">Submit location to server via ajax</button>      
          <br />
          <br />
          <%= submit_tag "Submit location to server via form submit" %>
          <br />
          <br />
          <button class="clearAndSubmit">Clear form and submit</button>      
        <% end %>
      </body>
    </html>
    
    # application_controller.rb
    class ApplicationController < ActionController::Base
      before_action do
        # Implemented before_action for demonstration purposes. Should be moved into action.
    
        if params[:lat].present? && params[:long].present?
          Rails.logger.info(['Received lat&long from AJAX request', {lat: params[:lat], long: params[:long]}])
          # current_user.lat = params[:lat]
          # current_user.lat = params[:lng]
          # current_user.save!
        end
      end
    end
    
    # gemfile.rb
    #...
    gem 'geocoder'
    

    【讨论】:

    • 根据我的问题,我要求它在本地主机上工作
    • 如果您将 AJAX 请求从 JavaScript 发送到 Rails,它将在 localhost 上运行。在我提供的代码 sn-p 中,您可以看到 AJAX 请求的示例。直接忽略geocodergem相关的代码
    【解决方案2】:

    你可以使用geocoder gem

    首先打开你的 Gemfiles 并添加这一行

    gem 'geocoder'
    

    从终端运行 bundle install 来安装 gem 文件 然后运行 ​​rails 控制台进行测试,这里是搜索伦敦唐宁街 10 号的经纬度的示例

    results = Geocoder.search("10 Downing Street, london")
    latitude = results.first.coordinates[0]
    longitude = results.first.coordinates[1]
    

    【讨论】:

      猜你喜欢
      • 2019-03-25
      • 2016-09-29
      • 1970-01-01
      • 2022-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多