1

我一直在嘗試4年以上,嘗試找出在我的Rails應用中使用谷歌地圖的方法。我目前正在嘗試Rails 5.谷歌地圖 - 設置它與Rails 5一起工作 - 地理編碼器不進行地理編碼

我最近發佈了這個求救信息。我收到的建議並沒有爲我工作,所以我現在再試一次,看看別人是否可能知道一些事情。 Rails 5, Gmaps4Rails - setup

我有模型的組織和地址。

的關聯是:

組織

has_many :addresses, as: :addressable 
    accepts_nested_attributes_for :addresses, reject_if: :all_blank, allow_destroy: true 

地址

belongs_to :addressable, :polymorphic => true, optional: true 

我不再試圖與gmaps4rails寶石摸不着頭腦。我從我的寶石文件中刪除了它。儘管如此,我仍然擁有geocoder gem。

在我的地址控制器,我有

def index 
    @addresses = Address.all 
    end 

    def show 

    end 

在我的組織控制,我有

def index 
    @organisations = Organisation.all 
    authorize @organisations 
    end 

    def show 
    @addresses = @organisation.addresses.all 

    end 

在我的組織觀,我有

<%= render 'contacts/addresses/map' %> 

在我的地址視圖,我有

<%= javascript_tag do %> 
    var addresses = <%= raw @addresses.to_json %>; 
<% end %> 


<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV["GOOGLE_MAPS_API_KEY"] %>&callback=initMap" 
    async defer></script> 

在我address.js,我有

function initMap() { 
    var map = new google.maps.Map(document.getElementById('map'), { 
    zoom: 4 
    }); 
    var bounds = new google.maps.LatLngBounds(); 

    var n = addresses.length; 
    for (var i = 0; i < n; i++) { 
    var address = new google.maps.Marker({ 
     position: {lat: parseFloat(addresses[i].latitude), lng: parseFloat(addresses[i].longitude)}, 
     title: addresses[i].name, 
     map: map 
    }); 
    bounds.extend(address.position); 
    } 

    map.fitBounds(bounds); 
} 

雖然變焦設置似乎沒有工作,這實際上將呈現一個地圖提供的,我設置從控制檯的緯度和經度領域。

如果我沒有在控制檯中手動設置這些領域,我得到一個錯誤,指出:

js?key=.....&callback=initMap:42 Uncaught RangeError: Maximum call stack size exceeded 

這個帖子Uncaught RangeError: Maximum call stack size exceeded Google maps when I try to set bounds表明,問題是由緯度/經度座標引起不被傳遞到JS。這解釋了我的問題,因爲我的控制檯顯示這些屬性保存爲零。

在我的地址模型我有:

class Address < ApplicationRecord 

    geocoded_by :full_address # can also be an IP address 

    # --------------- associations 

    belongs_to :addressable, :polymorphic => true, optional: true 

    # --------------- scopes 

    # --------------- validations 


    # --------------- class methods 


    def unit_line 
    if self.unit.present? 
     ['Unit', unit.titlecase].join(' ') 
    end 
    end 

    def first_line 
    [street_number, street.titlecase].join(' ') 
    end 

    def middle_line 
    if self.building.present? 
     ['Building', building.titlecase].join(' ') 
    end 
    end 

    def last_line 
    [city.titlecase, region.upcase, zip].join(' ') 
    end 

    # def country_name 
    # # self.country = ISO3166::Country[country] 
    # # country.translations[I18n.locale.to_s] || country.name 

    # # iso_country = ISO3166::Country.find_by_name(country) # `country` should be name like 'Australia' 
    # # iso_country.translations[I18n.locale.to_s] || iso_country.name 
    # end 

    # def country_name 
    # self.country = ISO3166::Country[country] 
    # country.translations[I18n.locale.to_s] || country.name 
    # end 

    def country_name 
    country = self.country 
    ISO3166::Country[country] 
    end 



    def full_address 
    [self.unit_line, first_line, middle_line, last_line, country_name].compact.join("<br>").html_safe 
    end 


    # --------------- callbacks 

    after_create :geocode#, if self.full_address.changed? 

我也曾嘗試:

after_validation :geocode 



    # --------------- instance methods 

    # --------------- private methods 



end 

我的地址表中有緯度和經度小數屬性。我正在使用Geocoder gem,並希望地址在創建後進行地理編碼。

我有一個初始化器與geocoder.rb:

Geocoder.configure(
    # Geocoding options 
    :timeout  => 3,   # geocoding service timeout (secs) 
    :lookup  => :google,  # name of geocoding service (symbol) 
    :language  => :en,   # ISO-639 language code 
    :use_https => true,  # use HTTPS for lookup requests? (if supported) 
    # :http_proxy => nil,   # HTTP proxy server (user:[email protected]:port) 
    # :https_proxy => nil,   # HTTPS proxy server (user:[email protected]:port) 
    :api_key  => nil,   # API key for geocoding service 
    # :cache  => nil,   # cache object (must respond to #[], #[]=, and #keys) 
    # :cache_prefix => "geocoder:", # prefix (string) to use for all cache keys 

    # exceptions that should not be rescued by default 
    # (if you want to implement custom error handling); 
    # supports SocketError and TimeoutError 
    # :always_raise => [], 

    # calculation options 
    :units  => :km,  # :km for kilometers or :mi for miles 
    # :distances => :linear # :spherical or :linear 
) 

有人能看到什麼,我需要做的就是這個工作?

儘管在我的address.rb請求地理編碼之後進行了驗證,但我的lat/lng屬性未用座標更新。

控制檯輸出

a = Address.first 
    Address Load (30.2ms) SELECT "addresses".* FROM "addresses" ORDER BY "addresses"."id" ASC LIMIT $1 [["LIMIT", 1]] 
=> #<Address id: 8, unit: "16", building: "asdf", street_number: "15", street: "Johnston Street", city: "Balmain East", region: "NSW", zip: "2041", country: "AU", time_zone: "Midway Island", addressable_id: 1, addressable_type: "Organisation", description: "registered_office", created_at: "2016-11-10 00:16:50", updated_at: "2016-11-10 00:16:50", latitude: nil, longitude: nil> 

埃裏克的建議

我試圖採取埃裏克的建議,觸發地理編碼,但它不更新的緯度/經度座標。

Address.where(latitude: nil).or(Address.where(longitude: nil)).each{|marker| marker.save} 
    Address Load (16.3ms) SELECT "addresses".* FROM "addresses" WHERE ("addresses"."latitude" IS NULL OR "addresses"."longitude" IS NULL) 
    (2.0ms) BEGIN 
    (0.8ms) COMMIT 
=> [#<Address id: 8, unit: "1", building: "asdf", street_number: "10", street: "Darling Street", city: "Balmain", region: "NSW", zip: "2041", country: "AU", time_zone: "Midway Island", addressable_id: 1, addressable_type: "Organisation", description: "registered_office", created_at: "2016-11-10 00:16:50", updated_at: "2016-11-10 00:16:50", latitude: nil, longitude: nil>] 
+0

在控制檯中,是什麼'Address.first.latitude'返回? –

+0

無..................... – Mel

+0

這就是你的問題。忘記控制器,視圖和JavaScript。你的問題是在模型 –

回答

0

像往常一樣,開始簡單,慢慢地添加更多的代碼。 我使用了我以前的answer的基本Rails應用程序。

我將gem 'geocoder'添加到Gemfile。

bundle install後,我加入

geocoded_by :name # can also be an IP address 
after_validation :geocode 

我標記類,其中已經有緯度和經度定義爲:小數屬性。

rails c

Marker.create(:name => 'New Dehli') 
Marker.create(:name => 'New-York') 

做了,他們出現在地圖上!

注意:如果由於某些原因某些標記沒有座標,地圖將不會顯示,並且您將在js控制檯中收到「太多遞歸」錯誤。 爲了避免這種情況,可以確保所有標記都在你的模型使after_validation :geocode,並在控制檯啓動這個座標:

Marker.where(latitude: nil).or(Marker.where(longitude: nil)).each{|marker| marker.save} 

保存標記觸發驗證,這會觸發地理編碼。

如果由於某種原因,你仍然有非地理編碼標記,改變你的JS到:

function initMap() { 
    var map = new google.maps.Map(document.getElementById('map'), { 
    zoom: 4 
    }); 
    var bounds = new google.maps.LatLngBounds(); 

    var n = markers.length; 
    for (var i = 0; i < n; i++) { 
    var lat = markers[i].latitude; 
    var lng = markers[i].longitude; 
    if (lat == null || lng ==null){ 
     console.log(markers[i].name + " doesn't have coordinates"); 
    }else { 
     var marker = new google.maps.Marker({ 
     position: {lat: parseFloat(lat), lng: parseFloat(lng)}, 
     title: markers[i].name, 
     map: map 
     }); 
     bounds.extend(marker.position); 
    } 
    } 
    map.fitBounds(bounds); 
} 
+0

當我試用這個js時,控制檯顯示:undefined沒有座標 – Mel

+0

您的模型沒有名稱。你可以使用標記[i] .id –