我需要使用 haversine 函数计算两点之间的 return 距离

I need to return distances between two points using the haversine function

我需要 return 使用 haversine 函数计算两点之间的距离。我使用范围从数据库中检索一组坐标。但是我在遍历数组到每个创建的对之间的 return 距离时遇到了麻烦。

在 show() 中,我希望查看的地址是 base/origin 点,然后它应该循环遍历数据库以与所有其他地址点配对 return 它们的距离基于@origin.

目前,我只有一个值return。我真的需要帮助。

下面是我的代码

class AddressesController < ApplicationController
  before_action :set_address, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!

  # GET /addresses
  # GET /addresses.json
  def index
    @addresses = Address.all
  end

  def haversine_distance(geo_a, geo_b, miles=false)
    # Get latitude and longitude
    lat1, lon1 = geo_a
    lat2, lon2 = geo_b
  
    # Calculate radial arcs for latitude and longitude
    dLat = (lat2 - lat1) * Math::PI / 180
    dLon = (lon2 - lon1) * Math::PI / 180
  
    a = Math.sin(dLat / 2) * 
        Math.sin(dLat / 2) +
        Math.cos(lat1 * Math::PI / 180) * 
        Math.cos(lat2 * Math::PI / 180) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2)
  
    c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
    
    d = 6371 * 1000 * c # in meters
  end

  # GET /addresses/1
  # GET /addresses/1.json
  def show()
    @origin = [@address.latitude, @address.longitude]
    @destination = Address.get_lat_lon_array

    @destination.each do |dest|
      @distance = haversine_distance(@origin, dest).to_i
    end
  end

  # GET /addresses/new
  def new
    @address = Address.new
  end

  # GET /addresses/1/edit
  def edit
  end

  # POST /addresses
  # POST /addresses.json
  def create
    @address = Address.new(address_params)
    @address.user_id = current_user.id

    respond_to do |format|
      if @address.save
        format.html { redirect_to dashboard_path, notice: 'Address was successfully created.' }
        format.json { render :show, status: :created, location: @address }
      else
        format.html { render :new }
        format.json { render json: @address.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /addresses/1
  # PATCH/PUT /addresses/1.json
  def update
    respond_to do |format|
      if @address.update(address_params)
        format.html { redirect_to my_address_path, notice: 'Address was successfully updated.' }
        format.json { render :show, status: :ok, location: @address }
      else
        format.html { render :edit }
        format.json { render json: @address.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /addresses/1
  # DELETE /addresses/1.json
  def destroy
    @address.destroy
    respond_to do |format|
      format.html { redirect_to addresses_url, notice: 'Address was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_address
      @address = Address.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def address_params
      params.require(:address).permit(:landmark, :longitude, :latitude)
    end
end

<%= render "layouts/main-nav" %>

<div class="container py-5 dash-view">
    <div class="row" id="dash">
      <%= render "layouts/left" %>
      <div class="col-md-8">
        <p><%= @address.landmark %></p>
        <p><%= @distance %> meters</p>
      </div>
    </div>    
  </div>
</div>

class Address < ApplicationRecord
  validates :latitude, :longitude, :landmark, presence: true

  belongs_to :user

  scope :get_lat_lon_array, -> { pluck(:latitude, :longitude) }
end

我希望我的输出是 table 在 relation/from 中其他地址到当前用户地址

距离的显示视图

如果我理解你的问题,你需要的是Array#map这样使用:

@destination =  [[0.384687e0, 0.32658527e2], [0.393035e0, 0.3264051e2], [0.323493e0, 0.32647846e2], [0.364948e0, 0.32637298e2], [0.309571e0, 0.32652247e2], [0.386782e0, 0.32652977e2]]
origin = [0.384687e0, 0.32658527e2]

@distances = @destination.map { |point| haversine_distance(point, origin).to_i }
@distances #=> [0, 2208, 6907, 3223, 8382, 660]

文档中的示例和 link 应该对您有所帮助。