I want to know which thingy is centered on a given city. Both thingy and city have a lat and a lng attribute, ad lat and lng are both floats in the mysql database. knowing how clever ActiveRecord::Base is I wanted to do: City.find_by_lat_and_lng(self.lat, self.lng) but that interprets lat and lng as SELECT * FROM `cities` WHERE (`cities`.`lat` = ''50.12'' AND `cities`.`lng` = ''-5.7'') LIMIT 1 and since lat/lng are floats that won''t work, I would have thought that City.find(:first, :conditions => [ "lat = ? AND lng = ?", self.lat, self.lng ]) SELECT * FROM `cities` WHERE (lat = 50.13 AND lng = -5.56) LIMIT 1 would work but it returns nothing. what I had to do was City.find(:first, :conditions => [ "lat LIKE ? AND lng LIKE ?", self.lat, self.lng ]) which becomes SELECT * FROM `cities` WHERE (lat LIKE 50.13 AND lng LIKE -5.56) LIMIT 1 and works. Surely the first case is an ActiveRecord::Base problem in that it ought to interpret a float as a float and not a string (LIKE), the second is a mysql problem in that the query is good SQL and the third is just wrong, although it does work. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
float just does not play well with ''=='', however represented. You nearly always need to provide some form of tolerance to allow for the inherent imprecision of the internal representation. Given the application, you probably need to provide some circular probability of error regarding fixing the spherical co-ordinate centre in any case. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Col, Take a peek at GeoKit: http://geokit.rubyforge.org/ BTW, use Decimal (BigDecimal?) for your lats & lngs. Better precision. To wit, I have an Addresses table declared as follows: create_table :addresses, :force => true do |t| t.string :full_address, :street_address, :city, :state, :zip, :country t.decimal :lat, :lng, :precision => 15, :scale => 10 end Works great for me. GeoKit lets you do all the lookup goodness, including some nice "find" overrides. -Danimal On Apr 11, 1:33 pm, Col Wilson <col.wilson.em...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> I want to know which thingy is centered on a given city. Both thingy > and city have a lat and a lng attribute, ad lat and lng are both > floats in the mysql database. > > knowing how clever ActiveRecord::Base is I wanted to do: > > City.find_by_lat_and_lng(self.lat, self.lng) > > but that interprets lat and lng as > > SELECT * FROM `cities` WHERE (`cities`.`lat` = ''50.12'' AND > `cities`.`lng` = ''-5.7'') LIMIT 1 > > and since lat/lng are floats that won''t work, > > I would have thought that > > City.find(:first, :conditions => [ "lat = ? AND lng = ?", self.lat, > self.lng ]) > > SELECT * FROM `cities` WHERE (lat = 50.13 AND lng = -5.56) LIMIT 1 > > would work but it returns nothing. > > what I had to do was > > City.find(:first, :conditions => [ "lat LIKE ? AND lng LIKE ?", > self.lat, self.lng ]) > > which becomes > > SELECT * FROM `cities` WHERE (lat LIKE 50.13 AND lng LIKE -5.56) > LIMIT 1 > > and works. > > Surely the first case is an ActiveRecord::Base problem in that it > ought to interpret a float as a float and not a string (LIKE), the > second is a mysql problem in that the query is good SQL and the third > is just wrong, although it does work.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks for that. On Apr 11, 10:14 pm, Danimal <fightonfightw...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Col, > > Take a peek at GeoKit:http://geokit.rubyforge.org/ > > BTW, use Decimal (BigDecimal?) for your lats & lngs. Better precision. > To wit, I have an Addresses table declared as follows: > > create_table :addresses, :force => true do |t| > > t.string :full_address, :street_address, :city, :state, :zip, :country > t.decimal :lat, :lng, :precision => 15, :scale => 10 > end > > Works great for me. GeoKit lets you do all the lookup goodness, > including some nice "find" overrides. > > -Danimal > > On Apr 11, 1:33 pm, Col Wilson <col.wilson.em...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> > wrote:> I want to know which thingy is centered on a given city. Both thingy > > and city have a lat and a lng attribute, ad lat and lng are both > > floats in the mysql database. > > > knowing how clever ActiveRecord::Base is I wanted to do: > > > City.find_by_lat_and_lng(self.lat, self.lng) > > > but that interprets lat and lng as > > > SELECT * FROM `cities` WHERE (`cities`.`lat` = ''50.12'' AND > > `cities`.`lng` = ''-5.7'') LIMIT 1 > > > and since lat/lng are floats that won''t work, > > > I would have thought that > > > City.find(:first, :conditions => [ "lat = ? AND lng = ?", self.lat, > > self.lng ]) > > > SELECT * FROM `cities` WHERE (lat = 50.13 AND lng = -5.56) LIMIT 1 > > > would work but it returns nothing. > > > what I had to do was > > > City.find(:first, :conditions => [ "lat LIKE ? AND lng LIKE ?", > > self.lat, self.lng ]) > > > which becomes > > > SELECT * FROM `cities` WHERE (lat LIKE 50.13 AND lng LIKE -5.56) > > LIMIT 1 > > > and works. > > > Surely the first case is an ActiveRecord::Base problem in that it > > ought to interpret a float as a float and not a string (LIKE), the > > second is a mysql problem in that the query is good SQL and the third > > is just wrong, although it does work. > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Not sure if it applied to what you''re doing, but it seems like you''d have a tolerance issue even without the imprecision of the float. My city is roughly 40N 86W, but that wouldn''t find it in an ''='' query. Maybe a between query with a fudge factor, like: :conditions => ["lat between ? and ? and lon between ? and ?",lat- fudge,lat+fudge,lon-fudge,lon+fudge] To keep it DRY, you could build your own finder method on city. -Mack On Apr 11, 8:09 pm, Col Wilson <col.wilson.em...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> Thanks for that. > > On Apr 11, 10:14 pm, Danimal <fightonfightw...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Col, > > > Take a peek at GeoKit:http://geokit.rubyforge.org/ > > > BTW, use Decimal (BigDecimal?) for your lats & lngs. Better precision. > > To wit, I have an Addresses table declared as follows: > > > create_table :addresses, :force => true do |t| > > > t.string :full_address, :street_address, :city, :state, :zip, :country > > t.decimal :lat, :lng, :precision => 15, :scale => 10 > > end > > > Works great for me. GeoKit lets you do all the lookup goodness, > > including some nice "find" overrides. > > > -Danimal > > > On Apr 11, 1:33 pm, Col Wilson <col.wilson.em...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> > > wrote:> I want to know which thingy is centered on a given city. Both thingy > > > and city have a lat and a lng attribute, ad lat and lng are both > > > floats in the mysql database. > > > > knowing how clever ActiveRecord::Base is I wanted to do: > > > > City.find_by_lat_and_lng(self.lat, self.lng) > > > > but that interprets lat and lng as > > > > SELECT * FROM `cities` WHERE (`cities`.`lat` = ''50.12'' AND > > > `cities`.`lng` = ''-5.7'') LIMIT 1 > > > > and since lat/lng are floats that won''t work, > > > > I would have thought that > > > > City.find(:first, :conditions => [ "lat = ? AND lng = ?", self.lat, > > > self.lng ]) > > > > SELECT * FROM `cities` WHERE (lat = 50.13 AND lng = -5.56) LIMIT 1 > > > > would work but it returns nothing. > > > > what I had to do was > > > > City.find(:first, :conditions => [ "lat LIKE ? AND lng LIKE ?", > > > self.lat, self.lng ]) > > > > which becomes > > > > SELECT * FROM `cities` WHERE (lat LIKE 50.13 AND lng LIKE -5.56) > > > LIMIT 1 > > > > and works. > > > > Surely the first case is an ActiveRecord::Base problem in that it > > > ought to interpret a float as a float and not a string (LIKE), the > > > second is a mysql problem in that the query is good SQL and the third > > > is just wrong, although it does work.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---