README.md in geocoder-1.4.0 vs README.md in geocoder-1.4.1

- old
+ new

@@ -1,11 +1,11 @@ Geocoder ======== -Geocoder is a complete geocoding solution for Ruby. With Rails it adds geocoding (by street or IP address), reverse geocoding (finding street address based on given coordinates), and distance queries. It's as simple as calling `geocode` on your objects, and then using a scope like `Venue.near("Billings, MT")`. +Geocoder is a complete geocoding solution for Ruby. With Rails, it adds geocoding (by street or IP address), reverse geocoding (finding street address based on given coordinates), and distance queries. It's as simple as calling `geocode` on your objects, and then using a scope like `Venue.near("Billings, MT")`. -_Please note that this README is for the current `HEAD` and may document features not present in the latest gem release. For this reason, you may want to instead view the README for your particular version._ +_Please note that this README is for the current `HEAD` and may document features not present in the latest gem release. For this reason, you may want to instead view the README for your [particular version](https://github.com/alexreisner/geocoder/releases)._ Compatibility ------------- @@ -45,11 +45,11 @@ Your model must have two attributes (database columns) for storing latitude and longitude coordinates. By default they should be called `latitude` and `longitude` but this can be changed (see "Model Configuration" below): rails generate migration AddLatitudeAndLongitudeToModel latitude:float longitude:float rake db:migrate -For geocoding your model must provide a method that returns an address. This can be a single attribute, but it can also be a method that returns a string assembled from different attributes (eg: `city`, `state`, and `country`). +For geocoding, your model must provide a method that returns an address. This can be a single attribute, but it can also be a method that returns a string assembled from different attributes (eg: `city`, `state`, and `country`). Next, your model must tell Geocoder which method returns your object's geocodable address: geocoded_by :full_street_address # can also be an IP address after_validation :geocode # auto-fetch coordinates @@ -100,11 +100,11 @@ include Geocoder::Model::Mongoid geocoded_by :address, :skip_index => true ### Bulk Geocoding -If you have just added geocoding to an existing application with a lot of objects you can use this Rake task to geocode them all: +If you have just added geocoding to an existing application with a lot of objects, you can use this Rake task to geocode them all: rake geocode:all CLASS=YourModel If you need reverse geocoding instead, call the task with REVERSE=true: @@ -242,20 +242,20 @@ def address [street, city, state, country].compact.join(', ') end -For reverse geocoding you can also specify an alternate name attribute where the address will be stored, for example: +For reverse geocoding, you can also specify an alternate name attribute where the address will be stored. For example: reverse_geocoded_by :latitude, :longitude, :address => :location # ActiveRecord reverse_geocoded_by :coordinates, :address => :loc # MongoDB -You can also configure a specific lookup for your model which will override the globally-configured lookup, for example: +You can also configure a specific lookup for your model which will override the globally-configured lookup. For example: geocoded_by :address, :lookup => :yandex -You can also specify a proc if you want to choose a lookup based on a specific property of an object, for example you can use specialized lookups for different regions: +You can also specify a proc if you want to choose a lookup based on a specific property of an object. For example, you can use specialized lookups for different regions: geocoded_by :address, :lookup => lambda{ |obj| obj.geocoder_lookup } def geocoder_lookup if country_code == "RU" @@ -276,11 +276,11 @@ distance = 20 center_point = [40.71, 100.23] box = Geocoder::Calculations.bounding_box(center_point, distance) Venue.within_bounding_box(box) -This can also dramatically improve query performance, especially when used in conjunction with indexes on the latitude/longitude columns. Note, however, that returned results do not include `distance` and `bearing` attributes. Note that `#near` performs both bounding box and radius queries for speed. +This can also dramatically improve query performance, especially when used in conjunction with indexes on the latitude/longitude columns. Note, however, that returned results do not include `distance` and `bearing` attributes. Also note that `#near` performs both bounding box and radius queries for speed. You can also specify a minimum radius (if you're using ActiveRecord and not Sqlite) to constrain the lower bound (ie. think of a donut, or ring) by using the `:min_radius` option: box = Geocoder::Calculations.bounding_box(center_point, distance, :min_radius => 10.5) @@ -291,11 +291,11 @@ Advanced Geocoding ------------------ -So far we have looked at shortcuts for assigning geocoding results to object attributes. However, if you need to do something fancy you can skip the auto-assignment by providing a block (takes the object to be geocoded and an array of `Geocoder::Result` objects) in which you handle the parsed geocoding result any way you like, for example: +So far we have looked at shortcuts for assigning geocoding results to object attributes. However, if you need to do something fancy, you can skip the auto-assignment by providing a block (takes the object to be geocoded and an array of `Geocoder::Result` objects) in which you handle the parsed geocoding result any way you like, for example: reverse_geocoded_by :latitude, :longitude do |obj,results| if geo = results.first obj.city = geo.city obj.zipcode = geo.postal_code @@ -353,11 +353,11 @@ :cache => Redis.new, :cache_prefix => "..." ) -Please see lib/geocoder/configuration.rb for a complete list of configuration options. Additionally, some lookups have their own configuration options, some of which are directly supported by Geocoder. For example, to specify a value for Google's `bounds` parameter: +Please see `lib/geocoder/configuration.rb` for a complete list of configuration options. Additionally, some lookups have their own configuration options, some of which are directly supported by Geocoder. For example, to specify a value for Google's `bounds` parameter: # with Google: Geocoder.search("Paris", :bounds => [[32.1,-95.9], [33.9,-94.3]]) Please see the [source code for each lookup](https://github.com/alexreisner/geocoder/tree/master/lib/geocoder/lookups) to learn about directly supported parameters. Parameters which are not directly supported can be specified using the `:params` option, by which you can pass arbitrary parameters to any geocoding service. For example, to use Nominatim's `countrycodes` parameter: @@ -390,11 +390,11 @@ :service => :omni } ) -The above combines global and service-specific options and could be useful if you specify different geocoding services for different models or under different conditions. Lookup-specific settings override global settings so, for example, in the above the timeout for all lookups would be 2 seconds, except for Yandex which would be 5. +The above combines global and service-specific options and could be useful if you specify different geocoding services for different models or under different conditions. Lookup-specific settings override global settings. In the above example, the timeout for all lookups would be 2 seconds, except for Yandex which would be 5. ### Street Address Services The following is a comparison of the supported geocoding APIs. The "Limitations" listed for each are a very brief and incomplete summary of some special limitations beyond basic data source attribution. Please read the official Terms of Service for a service before using it. @@ -455,10 +455,21 @@ * **Languages**: ? * **Documentation**: http://wiki.openstreetmap.org/wiki/Nominatim * **Terms of Service**: http://wiki.openstreetmap.org/wiki/Nominatim_usage_policy * **Limitations**: Please limit request rate to 1 per second and include your contact information in User-Agent headers (eg: `Geocoder.configure(:http_headers => { "User-Agent" => "your contact info" })`). [Data licensed under Open Database License (ODbL) (you must provide attribution).](http://www.openstreetmap.org/copyright) +#### LocationIQ (`:location_iq`) + +* **API key**: required +* **Quota**: 6 request/second (30k req/day), then ability to purchase more +* **Region**: world +* **SSL support**: yes +* **Languages**: ? +* **Documentation**: http://locationiq.org/#docs +* **Terms of Service**: https://unwiredlabs.com/tos +* **Limitations**: [Data licensed under Open Database License (ODbL) (you must provide attribution).](http://www.openstreetmap.org/copyright) + #### OpenCageData (`:opencagedata`) * **API key**: required * **Key signup**: http://geocoder.opencagedata.com * **Quota**: 2500 requests / day, then ability to purchase more (free during beta) @@ -589,21 +600,21 @@ * **Limitations**: See terms * **Notes**: Configure your self-hosted pelias with the `endpoint` option: `Geocoder.configure(:lookup => :pelias, :api_key => 'your_api_key', :pelias => {:endpoint => 'self.hosted/pelias'})`. Defaults to `localhost`. #### Data Science Toolkit (`:dstk`) -Data Science Toolkit provides an API whose reponse format is like Google's but which can be set up as a privately hosted service. +Data Science Toolkit provides an API whose response format is like Google's but which can be set up as a privately hosted service. * **API key**: none * **Quota**: None quota if you are self-hosting the service. * **Region**: world * **SSL support**: ? * **Languages**: en * **Documentation**: http://www.datasciencetoolkit.org/developerdocs * **Terms of Service**: http://www.datasciencetoolkit.org/developerdocs#googlestylegeocoder * **Limitations**: No reverse geocoding. -* **Notes**: If you are hosting your own DSTK server you will need to configure the host name, eg: `Geocoder.configure(:lookup => :dstk, :host => "localhost:4567")`. +* **Notes**: If you are hosting your own DSTK server you will need to configure the host name, eg: `Geocoder.configure(:lookup => :dstk, :dstk => {:host => "localhost:4567"})`. #### Baidu (`:baidu`) * **API key**: required * **Quota**: No quota limits for geocoding @@ -683,11 +694,21 @@ * **Languages**: en * **Documentation**: https://latlon.io/documentation * **Terms of Service**: ? * **Limitations**: No restrictions on use +#### Base Adresse Nationale FR (`:ban_data_gouv_fr`) +* **API key**: none +* **Quota**: none +* **Region**: FR +* **SSL support**: yes +* **Languages**: en / fr +* **Documentation**: https://adresse.data.gouv.fr/api/ (in french) +* **Terms of Service**: https://adresse.data.gouv.fr/faq/ (in french) +* **Limitations**: [Data licensed under Open Database License (ODbL) (you must provide attribution).](http://openstreetmap.fr/ban) + ### IP Address Services #### FreeGeoIP (`:freegeoip`) * **API key**: none @@ -846,11 +867,11 @@ ) Caching ------- -It's a good idea, when relying on any external service, to cache retrieved data. When implemented correctly it improves your app's response time and stability. It's easy to cache geocoding results with Geocoder, just configure a cache store: +When relying on any external service, it's always a good idea to cache retrieved data. When implemented correctly, it improves your app's response time and stability. It's easy to cache geocoding results with Geocoder -- just configure a cache store: Geocoder.configure(:cache => Redis.new) This example uses Redis, but the cache store can be any object that supports these methods: @@ -873,21 +894,21 @@ Geocoder::Lookup.get(:google).cache.expire(:all) # expire cached results for Google Lookup # expire all cached results for all Lookups. # Be aware that this methods spawns a new Lookup object for each Service Geocoder::Lookup.all_services.each{|service| Geocoder::Lookup.get(service).cache.expire(:all)} -Do *not* include the prefix when passing a URL to be expired. Expiring `:all` will only expire keys with the configured prefix (won't kill every entry in your key/value store). +Do *not* include the prefix when passing a URL to be expired. Expiring `:all` will only expire keys with the configured prefix -- it will *not* expire every entry in your key/value store. -For an example of a cache store with URL expiry please see examples/autoexpire_cache.rb +For an example of a cache store with URL expiry, please see examples/autoexpire_cache.rb _Before you implement caching in your app please be sure that doing so does not violate the Terms of Service for your geocoding service._ Forward and Reverse Geocoding in the Same Model ----------------------------------------------- -If you apply both forward and reverse geocoding functionality to the same model (say users can supply an address or coordinates and you want to fill in whatever's missing), you will provide two address methods: +If you apply both forward and reverse geocoding functionality to the same model (i.e. users can supply an address or coordinates and you want to fill in whatever's missing), you will provide two address methods: * one for storing the fetched address (reverse geocoding) * one for providing an address to use when fetching coordinates (forward geocoding) For example: @@ -910,11 +931,11 @@ :longitude => :fetched_longitude # same here reverse_geocoded_by :latitude, :longitude end -The reason for this is that we don't want ambiguity when doing distance calculations. We need a single, authoritative source for coordinates! +We don't want ambiguity when doing distance calculations -- we need a single, authoritative source for coordinates! Once both forward and reverse geocoding has been applied, it is possible to call them sequentially. For example: @@ -922,15 +943,15 @@ after_validation :geocode, :reverse_geocode end -For certain geolocation services such as Google geolocation API this may cause issues during subsequent updates to database records if the longtitude and latitude coordinates cannot be associated known location address (on a large body of water for example). On subsequent callbacks the following call: +For certain geolocation services such as Google's geolocation API, this may cause issues during subsequent updates to database records if the longitude and latitude coordinates cannot be associated with a known location address (on a large body of water for example). On subsequent callbacks the following call: after_validation :geocode -will alter the longtitude and latitude attributes based on the location field, which would be the closest known location to the original coordinates. In this case it is better to add conditions to each call, as not to override coordinates that do not have known location addresses associated with them. +will alter the longitude and latitude attributes based on the location field, which would be the closest known location to the original coordinates. In this case it is better to add conditions to each call, as not to override coordinates that do not have known location addresses associated with them. For example: class Venue @@ -986,14 +1007,16 @@ 'country_code' => 'US' } ] ) -Note: - Keys must be strings not symbols when calling `add_stub` or `set_default_stub`. For example `'latitude' =>` not `:latitude =>`. +Notes: +- Keys must be strings not symbols when calling `add_stub` or `set_default_stub`. For example `'latitude' =>` not `:latitude =>`. +- To clear stubs (e.g. prior to another spec), use `Geocoder::Lookup::Test.reset`. This will clear all stubs _including the default stub_. + Command Line Interface ---------------------- When you install the Geocoder gem it adds a `geocode` command to your shell. You can search for a street address, IP address, postal code, coordinates, etc just like you can with the Geocoder.search method for example: @@ -1005,11 +1028,11 @@ State/province: Louisiana Postal code: 70112 Country: United States Google map: http://maps.google.com/maps?q=29.952211,-90.080563 -There are also a number of options for setting the geocoding API, key, and language, viewing the raw JSON reponse, and more. Please run `geocode -h` for details. +There are also a number of options for setting the geocoding API, key, and language, viewing the raw JSON response, and more. Please run `geocode -h` for details. Numeric Data Types and Precision -------------------------------- Geocoder works with any numeric data type (e.g. float, double, decimal) on which trig (and other mathematical) functions can be performed. @@ -1038,20 +1061,20 @@ For consistency with the rest of Geocoder, always use the `to_coordinates` method instead. Notes on Non-Rails Frameworks ----------------------------- -If you are using Geocoder with ActiveRecord and a framework other than Rails (like Sinatra or Padrino) you will need to add this in your model before calling Geocoder methods: +If you are using Geocoder with ActiveRecord and a framework other than Rails (like Sinatra or Padrino), you will need to add this in your model before calling Geocoder methods: extend Geocoder::Model::ActiveRecord Optimisation of Distance Queries -------------------------------- -In MySQL and Postgres the finding of objects near a given point is speeded up by using a bounding box to limit the number of points over which a full distance calculation needs to be done. +In MySQL and Postgres, the finding of objects near a given point is sped up by using a bounding box to limit the number of points over which a full distance calculation needs to be done. -To take advantage of this optimisation you need to add a composite index on latitude and longitude. In your Rails migration: +To take advantage of this optimisation, you need to add a composite index on latitude and longitude. In your Rails migration: add_index :table, [:latitude, :longitude] Distance Queries in SQLite @@ -1148,10 +1171,10 @@ Reporting Issues ---------------- -When reporting an issue, please list the version of Geocoder you are using and any relevant information about your application (Rails version, database type and version, etc). Also avoid vague language like "it doesn't work." Please describe as specifically as you can what behavior your are actually seeing (eg: an error message? a nil return value?). +When reporting an issue, please list the version of Geocoder you are using and any relevant information about your application (Rails version, database type and version, etc). Also avoid vague language like "it doesn't work." Please describe as specifically as you can what behavior you are actually seeing (eg: an error message? a nil return value?). Please DO NOT use GitHub issues to ask questions about how to use Geocoder. Sites like [StackOverflow](http://www.stackoverflow.com/) are a better forum for such discussions. ### Known Issue