Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 使用Maps API计算两个地址的距离,然后将每个距离保存到数据库_Ruby On Rails_Google Maps Api 3_Open Uri - Fatal编程技术网

Ruby on rails 使用Maps API计算两个地址的距离,然后将每个距离保存到数据库

Ruby on rails 使用Maps API计算两个地址的距离,然后将每个距离保存到数据库,ruby-on-rails,google-maps-api-3,open-uri,Ruby On Rails,Google Maps Api 3,Open Uri,我正在编写一个应用程序,根据距离将儿童与幼儿园进行匹配 我正在尝试使用Maps API计算多个地址之间的距离。 我想使用开放uri https://maps.googleapis.com/maps/api/distancematrix/json?origins=[address of child]&destinations=[adress of kindergarden]&key=XYZ 这就是对api的请求 我的想法是在孩子的创作过程结束后发送请求。 我将从数据库中获取孩子地

我正在编写一个应用程序,根据距离将儿童与幼儿园进行匹配

我正在尝试使用Maps API计算多个地址之间的距离。 我想使用开放uri

https://maps.googleapis.com/maps/api/distancematrix/json?origins=[address of child]&destinations=[adress of kindergarden]&key=XYZ
这就是对api的请求

我的想法是在孩子的创作过程结束后发送请求。 我将从数据库中获取孩子地址和幼儿园地址,并构建请求。
响应的距离将保存在每个孩子和幼儿园的关系表中 如何访问儿童和幼儿园的数据库条目? 然后将其保存到关系表

我当前的代码如下所示:

    def create
@child = Child.new child_params
@child.user = current_user
@child.save
origin = @child.adress
destination = @kiga.adress
response = open('https://maps.googleapis.com/maps/api/distancematrix/json?origins=' + [address of child] + '&destinations=' + [adress of kindergarden] + '&key=XYZ').read
relations.distance = response.rows.elements[0]

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

非常感谢您的帮助?

这里的问题是您试图以字符串形式打开URL,因此它正在查找一个以这种方式命名的文件,而该文件不存在

这里有两个选项:

1.使用httpartygem发出HTTP请求 这是我最喜欢的方法

gem文件中包含gem

gem 'HTTParty'
在控制器内发出请求:

url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" \
      "#{@child.adress}&destinations=#{@kiga.adress}&key=XYZ"
response = HTTParty.get(url)
require 'open-uri'
require 'JSON'

    def create
    @child = Child.new child_params
    @child.user = current_user
    @child.save
    origin = @child.adress
    destination = @kiga.adress
    
    # Parse the string url into a valid URI
    url = URI.parse(
        "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" \
        "#{@child.adress}&destinations=#{@kiga.adress}&key=XYZ"
    )
    # Open the URI just like you were doing
    response = open(url).read
    # Parse the string response in JSON format
    result = JSON.parse(response)

    # Extract the distance value in meters
    relations.distance = result["rows"].first["elements"].first["distance"]["value"]

    respond_to do |format|
        if @child.save
            format.html { redirect_to @child, notice: 'Child was successfully created.' }
            format.json { render :show, status: :created, location: @child }
        else
            format.html { render :new }
            format.json { render json: @child.errors, status: :unprocessable_entity }
    end
end
现在,如果要打印
response[“rows”]。first[“elements”]。first
的结果,您将看到如下输出:

{"distance"=>{"text"=>"15.4 km", "value"=>15405}, "duration"=>{"text"=>"17 mins", "value"=>1001}, "status"=>"OK"}
正如您所看到的,您有距离和持续时间信息。我猜您是在追求以米为单位的距离值,因此:

relations.distance = response["rows"].first["elements"].first["distance"]["value"]
注1:我故意在单词address(@child.address,@kiga.address)中复制了打字错误,以便代码与您的设置配合使用,但请考虑将其修改为@child.address和@kiga.address

注意2:为了简单起见,我没有对响应进行任何错误检查,这是您绝对应该注意的事情

注意3:记住将api密钥更改为有效密钥,为了简单起见,我将其硬编码为XYZ,就像您在问题中所做的那样

2.使用open uri将url解析为有效的uri 您必须在控制器的开头要求使用库
'open-uri'
'JSON'

url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" \
      "#{@child.adress}&destinations=#{@kiga.adress}&key=XYZ"
response = HTTParty.get(url)
require 'open-uri'
require 'JSON'

    def create
    @child = Child.new child_params
    @child.user = current_user
    @child.save
    origin = @child.adress
    destination = @kiga.adress
    
    # Parse the string url into a valid URI
    url = URI.parse(
        "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" \
        "#{@child.adress}&destinations=#{@kiga.adress}&key=XYZ"
    )
    # Open the URI just like you were doing
    response = open(url).read
    # Parse the string response in JSON format
    result = JSON.parse(response)

    # Extract the distance value in meters
    relations.distance = result["rows"].first["elements"].first["distance"]["value"]

    respond_to do |format|
        if @child.save
            format.html { redirect_to @child, notice: 'Child was successfully created.' }
            format.json { render :show, status: :created, location: @child }
        else
            format.html { render :new }
            format.json { render json: @child.errors, status: :unprocessable_entity }
    end
end
变量
result
(解析后)的内容如下所示:

{"destination_addresses"=>["Destination address"], "origin_addresses"=>["Origin address"], "rows"=>[{"elements"=>[{"distance"=>{"text"=>"15.4 km", "value"=>15405}, "duration"=>{"text"=>"17 mins", "value"=>1001}, "status"=>"OK"}]}], "status"=>"OK"}

如果您选择HTTParty方式或openuri+JSON解析方式,请确保检查响应状态代码。这两种方法都在我的计算机上进行了本地测试,并取得了成功


我希望这有帮助,干杯

另一种解决方案是看看这个宝石

如果您对您的子模型和Kiga模型进行地理编码,那么您可以很容易地获得它们之间的距离

enter code here
这是不做任何API调用的,GEM为您做这件事

它也有一个非常方便的方法返回位置附近的记录

@kiga.near(@child.coordinates, 10)
将返回所有具有10km@child坐标的Kiga