Proximity searches in Rails - ruby-on-rails

What proximity search options are there for Rails? (Perhaps with pros and cons of each?)
Is a postcode database the way to go?
or using Geocoding with a gem such as Geocoder?
Are there any best practises or gotchas to be aware of?
(Example usage, A Yellow Pages type app where businesses can list, and users can enter their postcode and find businesses that are close to them, or within a radius of specified miles.)
Update: The app is pretty much exactly like the example app above - Businesses can list in the app which is essential a directory (which will have categories for each type of business) and users can go to a category and sort the results by distance (after entering their postcode - so the businesses closest to them, gets shown first). There will be no searching by name or other criteria - it is a simple go to the 'Boxer Dog Breeders' page and sort by distance.

Well the answer depends on what you want to do. If you want simple proximity searches (within a radius and stuff) then the Geocoder gem is more than fine! Now, if you want more advanced search capabilities (polygon, multi-polygon searches etc) I would suggest to go with the PostrgeSQL database and the wonderful PostGIS extension. For use with Rails you should definitely check out the PostGIS adapter for ActiveRecord which comes from the author of a really nice gem called RGeo which uses the superfast libraries GEOS and Proj for the Geospatial calculations.
Otherwise if you find that you need a dedicated search server that has GIS capabilities then you should definitely use ElasticSearch and Ruby has a great gem to aid you with ES called Tire.
Hope I helped!

If you plan to add addational search criteria (eg. name of firm, category) or complex sorting and your DB will grow over 10000 I'm recommend using external search server. For example sphinx search + thinking sphinx.
Here is example of geosearching: http://freelancing-god.github.com/ts/en/geosearching.html
RoR model solutions (like Geocoder) are not very efficient with full text searching.

I don't have experience with Geocoding myself, but Alex Reisner's Geocoder gem looks like the best option, by a mile.
Geocoder is a complete geocoding solution for Ruby. With Rails it adds geocoding (by street or IP address), reverse geocoding (find 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").
Checkout the README for a full example on how to use it.

Related

Rails Geocoder MapIt functionality alternatives

I'm working with rails, geocoder and gmap4rails. Trying to figure out how to show boundaries of an ward district area in UK. Found mapit - Mapit by mySociaty . Would be amazing if anyone could suggest or point me in the direction for creating a similar functions in rails. I'm especially interested in functions like 'Touching this area' as showed in the mapit.mysociety.org site.
Google maps also show boundaries of an area e.g. google map example Shows boundaries for 'Roath' area. is there anyway retrieve that data from google ?
I also tested a lot of addresses with geocoder, looking up in google. Tried to Geocode from address administrative_area_level_1 2 and 3 as well as in locality or sublocality.
The results were very unreliable. Tried at least 20 addresses from birmigham city - only some of them returned administrative_area_level1,2,3 or locality or sublocality and most of the time it was wrong data.
Another website that is sort of showing ward areas with in a city is www.streetlife.com I think it only works for UK users. basically it takes a postcode from a user and then in their map they show users district and other district around it, which is pretty cool :) Does anyone know how it works ? or how to get something like that working in rails ?
I would really love to discuss this topic in more depth and figure out the best answers for it.
This question at gis.stackexchange is probably of use to you if you wish to use rails. The "touching" feature is fundamentally a PostGIS query, so you could build on top of anything that allowed you to make SQL queries to a PostgreSQL database - GeoDjango (on which MapIt is built) makes this nice, but you could certainly accomplish the same in rails with work.
You won't be able to get those boundaries you see out of Google Maps, I believe, as it's proprietary.
Geocoding is a separate topic - you may want to look at things like OpenStreetMap's Nominatim (MapQuest have a version) or GeoNames, which could supply a dataset you could use with geocoder - Ordnance Survey also publish GB datasets that could be of use.

Gmaps4Rails Google Map Interaction Nearest Location Feature Unfamiliar with Google Maps API

Currently I am building a rails application using the gmaps4rails gem. I have only been working on this for ten days,
http://greenearth.herokuapp.com/
I apologize I only have one dyne up so it may be quite slow on heroku.
I understand that the gem interacts with google js api v3 for me. Basicly I am making an rails application where I want to display trash bins locations on a google map. I have a table with an address as a column in the table, the gem allows me to take the address column and spit out markers on a map. I have to query all the address, translate them to json with a method provided by the gem (and its added to my model), then bring it out to my view. It will generate the required javascript.
I am quite tempted to switch to the geocoder gem because its a lot better documented. This gem just isn't well documented. I can't find questions on stackoverflow related to this gem.
My next step is to add a feature, where anybody can put in their most immediate address on a form and the map (google api) will calculate which of my trash bin location is nearest to this input address.
The gem's wiki is not well documented. I am not quite well versed with the google map api. In the mean time can someone point me to the correct tutorial? or the right direction?
After looking into it a bit more it seems the developer (apneadiving) is actually quite active, just not in the same place, see these guides on features: http://www.youtube.com/watch?v=Yg5-33zedqM
There is a second video as well.
Looking into it further I can't see a method in the documentation that calculates distance.
I recommend trying this tutorial:
http://briancray.com/posts/how-to-calculate-the-distance-between-two-addresses-with-javascript-and-google-maps-api
Or just following the Distance Matrix service from Google.
I haven't tried to use these alongside the gem so you may have to change the code based on existing variables. It should* be easier because you have addresses and Lats/longs saved already.
Also have you set the App to initally geolocate the user?
I'm working on a similar issue myself so will update when I get there.
OK so after looking at the different gems I would recommend using both geocoder and gmaps4rails to achieve what you want. I would recommend gmaps4rails for the map rendering and marker addition and to use Geocoder for the distance calculations. Unfortunately neither gem is fully comprehensive in these features.
There is a good railscast on how to display nearby locations via a form using geocoder: http://www.youtube.com/watch?v=mUvGAcaW3bA
The method in geocoder is simply:
#address.nearbys(20)
Where '20' is a radius within which results will be displayed based on your other entries. Alternatively you could grab the user's current location using:
request.ip / request.location
Declare this as a variable then display nearby bins results in the show view (covered in rails cast). Just note that current location will not work in test/dev environment because of the webrick address as it says on the gem's homepage.
Hope that helps!

Can anyone recommend a gem for searching that actually allows me to easily filter my results in ruby on rails?

I've tried thinking sphinx after being pointed in that direction and simple filtering seems impossible. I've googled and asked questions for 2 days now and it seems it can't be done which is shocking because it's something commonly done when searching on websites.
All I would like to do add filtering options to my search form such as filtering by one or a combination of:
When user hits browse page all the sites users are returned but showing 20 results per page
Filtering options
in: location
who are: sexual preference
between the ages: age range
and located in: country
My search page works fine because all I require is 1 textfield a user uses for finding users by email, username or full name. My browse page is a different story because I'm using 1 form with multiple text fields and one or two select fields.
Example
Is there a gem that does this easily and performs well at the same time?
or would doing this manually via find methods be the only way?
Kind regards
Apart from using Sphinx and Thinking Sphinx, you can think of those gems: meta_where and meta_search
However after reading your description I think Sphinx is the best choice here indeed.
You wrote that it seems impossible to apply simple filtering using Thinking Sphinx. Let me explain a bit of Thinking Sphinx within the post you mentioned under the link: Example
You can go for Elasticsearch. Ruby has the 'Tire' gem, which is a client for ElasticSearch http://www.elasticsearch.org/

How to implement keyword and location search with MongoDB?

I am trying to implement a web/smart phone app that allow users to search for places based on keywords and location and here is the requirement:
Users shall be able to search by typing in keywords and location; Locations can be zip code, city/state or current location from the mobile app (lat and long)
We would like to be able to customize relevance score; We need to be able to define our own relevance algorithm based on keyword matching, location matching and some other parameters.
We use ASP.NET MVC as our web development framework and MongoDB as a data store. We also maintain a list of all zipcode and city/state as well as their centroid (lat/long) in our database. Our thought is override the scoring that the full-text system provide (like Lucene scoring) with our own algorithm. I am trying to find the best solution to address this. I am wondering whether should we use MongoDB full-text search or try to use Lucene .NET or perhaps Solr? Any help/pointer/comment is always apprecated!
So as a starting point, MongoDB does not have support for full-text search.
It has some regex capabilities and you can index on arrays. So you can do some things here, like building an array of keywords to make basic text search possible.
However, this is a long way from what Solr and Sphinx.
The other big problem you'll have is with relevance scoring. It's going to be very difficult to perform any type of server-side relevance scoring with MongoDB. There's no really efficient version of a server-side stored procedure. You'll likely have to pull the results to a client or server dedicated to that scoring.

Geocoder vs Geokit for finding objects within X miles of a latitude/longitude coordinate?

Newbie to Rails. I am building an app where users create events at a certain location, and plan to host on heroku. Other users can view events taking place within x miles of their latitude/longitude. I'm looking for a solution that would help me fetch all events happening in an x mile radius. The options seem to be Geocoder and Geokit. Geokit seems to be more popular but doesn't seem to be ready for Rails 3. Is there an obvious choice for what I'm trying to do?
You should use MongoDB, which is provided via a Heroku addon. With Mongo you then have access to spacial queries ("find me all the events within this circle"): http://www.mongodb.org/display/DOCS/Geospatial+Indexing
Unfortunately if you try to use Postgres's geospacial indexing you will find that Heroku does not offer it by default.
Take a look at Mongoid which enables you to do ActiveRecord-style representations of your documents in Mongo, and is very easy to get going with.

Resources