0

tl;dr:

すべての Google マップ API 呼び出しをこのメソッドからクライアント側に移動したと思います。何かを見逃しましたが、何がわかりません。

tl;dr コード

geocoder gemnearの一部であるメソッドを呼び出しています。

Location.facilities.near(@center, 50, order: :distance).select(&:item_is_searchable)

Locations モデルのジオコーダー コードは次のとおりです。

geocoded_by :full_address

after_validation :geocode

def full_address
  string = ""
  string << "#{address}\n" if address
  string << "#{extended_address}\n" if extended_address
  string << "#{city}, " if city
  string << "#{state} " if state
  string << zip_code if zip_code
  string
end

これは、ジオコーダーの専門家が私を助けるのに十分な情報である可能性があります。そうでない場合は、ここに詳細があります。より多くの情報。

裏話

私は Rails アプリで Geocoder gem を使用して大成功を収めてきましたが、今では Google マップ API のレート制限に達しています。

1 か月ほど前にレート制限の問題が発生したため、ほとんどのリクエストをクライアント側に移動しました。私は何かを逃したと思います。

プログラムの流れ

  1. ユーザーが検索を入力します
  2. ブラウザが Google マップ API にリクエストを送信します
  3. Google マップ API が座標を返す
  4. ブラウザはそれらの座標をサーバーに送信します
  5. サーバーは座標に近い場所を検索します
  6. 検索した場所から施設や講師のリストを作成
  7. リストは表示のためにブラウザに返されます

最も関連性の高いステップは 5 だと思います。これは、理解できないことを行うためにジオコーダー gem を呼び出す場所であるためです。そのため、それに照準を合わせます (コンテキストのためにステップ 4 と 6 の一部をキャッチします)。

ジオコーディング

#searches_controller.rb
def by_location
  @search = Search.find_nearby_instructors_and_facilities params[:coordinates]
  render :json => @search
end

#search.rb
class Search
  include ActiveModel::Serialization
  include ActiveModel::SerializerSupport

  attr_accessor :facilities, :instructors, :center

  def self.find_nearby_instructors_and_facilities(center)
    search = Search.new(center)
    search.find_nearest if center
    search
  end

  def initialize(center)
    @center = center
    @instructors = Set.new
    @facilities = []
  end

  def find_nearest
    @locations = Location.facilities.near(@center, 50, order: :distance).select(&:item_is_searchable)
    @facilities = @locations.map(&:addressable_item)
    @facilities.each do |facility|
      active_instructors = facility.instructors.select(&:active?)
      @instructors.merge(active_instructors)
    end
  end
end

座標の Near メソッドによって生成される特定の SQL ステートメントの例を次に示します。(30.267153, -97.74306079999997)

SELECT locations.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((30.267153 - locations.latitude) * PI() / 180 / 2), 2) + COS(30.267153 * PI() / 180) * COS(locations.latitude * PI() / 180) * POWER(SIN((-97.7430608 - locations.longitude) * PI() / 180 / 2), 2))) AS distance, CAST(DEGREES(ATAN2( RADIANS(locations.longitude - -97.7430608), RADIANS(locations.latitude - 30.267153))) + 360 AS decimal) % 360 AS bearing FROM "locations" WHERE "locations"."addressable_item_type" = 'Facility' AND (locations.latitude BETWEEN 29.54349408444576 AND 30.99081191555424 AND locations.longitude BETWEEN -98.58093480507472 AND -96.90518679492527 AND 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((30.267153 - locations.latitude) * PI() / 180 / 2), 2) + COS(30.267153 * PI() / 180) * COS(locations.latitude * PI() / 180) * POWER(SIN((-97.7430608 - locations.longitude) * PI() / 180 / 2), 2))) <= 50) ORDER BY distance

他に役立つ情報があれば、お知らせください。

4

0 に答える 0