0

現在、最先端のものを使用してレールアプリを作成しています。Rails3、rSpec2、Ruby 1.9.2、および Geokit 1.5.0。ASCII-8Bit にない特殊文字を含む住所をジオコーディングしようとすると、次のエラーが発生します。

互換性のない文字エンコーディング: UTF-8 および ASCII-8BIT

トレースは次のようになります。

1) Spot Basic Validations should calculate lat and lng
    Failure/Error: spot = Spot.create!({
    incompatible character encodings: UTF-8 and ASCII-8BIT
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/geokit-1.5.0/lib/geokit/geocoders.rb:435:in `do_geocode'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/geokit-1.5.0/lib/geokit/geocoders.rb:126:in `geocode'
    # ./app/models/spot.rb:26:in `geocode_address'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb:409:in `_run_validation_callbacks'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activemodel-3.0.0.rc/lib/active_model/validations/callbacks.rb:53:in `run_validations!'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activemodel-3.0.0.rc/lib/active_model/validations.rb:168:in `valid?'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:55:in `valid?'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:75:in `perform_validations'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:49:in `save!'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/attribute_methods/dirty.rb:30:in `save!'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:242:in `block in save!'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:289:in `block in with_transaction_returning_status'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in `transaction'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:204:in `transaction'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:287:in `with_transaction_returning_status'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:242:in `save!'
    # /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:34:in `create!'
    # ./spec/models/spot_spec.rb:13:in `block (2 levels) in <top (required)>'

# coding: utf-8関連するすべてのファイル (仕様、工場、モデル) で使用しました。それでも、「Elsassers Straße 27」のような住所を使用すると、このエラーが発生します。

ヒントはありますか?Geokit はすでに 1.9.1 と互換性があり、したがって、このすべての新しいエンコーディングと互換性があると思いました。

4

5 に答える 5

3

CGI.escape を使用すると、予期しない結果が生じるため、お勧めできません。CGI.escape を使用した場合と使用しない場合の "Oslo, Norway" を試してみてください。私の言いたいことがわかるでしょう。

より良い解決策は、次の場所で Iconv を使用することです。

ic = Iconv.new('US-ASCII//IGNORE', 'UTF-8')
utf8location = ic.iconv(location)

乾杯!

編集: Wes Gamble からここでの編集の提案がありましたが、これは関連があると思います:

を使用//IGNOREすると、非 ASCII 文字がすべて削除されます。しかし、多くの場合 (ほとんどの場合)、正常にジオコーディングするために、ウムラウト (例: "Zürich" は "Zurich" になります) やカロン (例: "Niš" は "Nis" になります) などの特定の文字を音訳したい場合があります。非 ASCII 文字を無視すると、"Zürich" は "Zrich" になり、"Niš" は "Ni" になり、どちらも正常にジオコーディングされません。

このために使用したい

ic = Iconv.new('US-ASCII//TRANSLIT', 'UTF-8')

音訳を完了できない場合、変換によって例外がスローされることに注意してください。必ずそれを処理してください。

于 2011-07-06T11:46:14.047 に答える
1

CGI.escape は Geokit::Inflector::url_escape よりも正確なようです。

「Elsassers Straße 27」をエンコードした結果は次のとおりです。

>> CGI.escape(address)

=> "Elsassers+Stra%C3%9Fe+27"

その間

>> Geokit::Inflector::url_escape(address)

=> "Elsassers+Stra%C3e+27"

文字 ß は c39F として表示されます ( http://www.utf8-chartable.de/unicode-utf8-table.plによる)

さらに、デバッグステートメントが爆発していました(デバッグログが有効になっているかどうかを確認する理由があることはわかっていました:)

だから、これがGoogleGeocoder3の私の解決策です。他の人も同様の問題を抱えていると思います

module Geokit
  module Geocoders
    class GoogleGeocoder3 < Geocoder
      def self.do_geocode(address, options = {})
        bias_str = options[:bias] ? construct_bias_string_from_options(options[:bias]) : ''
        address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
        #use CGI.escape instead of Geokit::Inflector::url_escape
        url ="http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{CGI.escape(address_str)}#{bias_str}"
        res = self.call_geocoder_service(url)
        return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
        json = res.body
        # escape results of json
        logger.debug "Google geocoding. Address: #{address}. Result: #{CGI.escape(json)}"
        return self.json2GeoLoc(json, address)
      end
    end
  end
end
于 2011-08-31T21:24:30.750 に答える
0

Postgres と pg gem v0.8 を使用していますか? 0.9 にアップグレード

于 2010-09-25T13:35:59.530 に答える
0

非常に遅い回答であることはわかっていますが、この非互換性エラーをすべて処理する Geokit gem 用の Google ジオコーダーを作成しました。この Geocoder は、Google のジオコーディング サービスの最新の V3 API を使用します。利点は、XML を解析するのではなく、より高速な JSON を解析し、必要な gem Yajl (Ruby 用の超高速 json パーサー) と組み合わせると、はるかに高速になることです。私のベンチマークは、古い方法よりも約 1.5 倍高速であることを示しています。

https://github.com/rubymaniac/geokit-gem

于 2011-02-09T23:27:24.753 に答える
-1

私は同じ問題を抱えていたので、次のように CGI.escape() を追加して解決しました。

geo = Geokit::Geocoders::MultiGeocoder.geocode(CGI.escape(address))
于 2011-06-06T09:07:38.613 に答える