« October 2006 | Main | December 2006 »

GZoom enhancements

Nov 21 by Andre in Google Maps » , Javascript »

I added a few things to GZoom today. What's new:

  • GZoom now works on maps that move or are resized on the page
  • new "Sticky" mode -- can stay in zoom mode for multiple zooms
  • more flexible zoom button, can use images, arbitrary text, etc.
  • tested and confirmed to work with GMaps new Marker Manager
  • you can specify optional callback functions for the following events: buttonClick,dragStart,dragging,dragEnd

See the GZoom original post, the new example, or read on for details of what's updated. Or just grab the new code:

gzoom.js -- right-click --> save as
gzoom_uncompressed.js -- right-click --> save as

Read on much more detail . . .

Continue reading "GZoom enhancements" »

An Experiment with Visual and Semantic Relationships

Nov 16 by Andre in Javascript » , Web 2.0 » , jQuery »

I am very interested in online collaboration tools. This experiment is an early offshoot of some tools and techniques I am developing:

A visual 'map' as a collaborative workspace. In this case, the goal is to build a visual representation of the Web 2.0 space, including entities (people, concepts, companies) and relationships among those entities.

Feel free to participate! Just three things you need to do:

  • Drag things around . . .
  • Right click! (control-click on Mac)
  • Select "relationships" from the right-click popup

Try it out at http://web20.earthcode.com

Hey, want to sort your query by geographic distance?

Nov 14 by Andre in MySQL » , Ruby on Rails »
Sure you do. Here's a sample Rails action which finds the ten closest cities to the latitude/longitude you provide. Obviously, this presumes your City model has the fields latitude and longitude. These examples are for MySQL 5.
def nearby_cities
  lat,lng=params[:ll].split(',').collect{|e|e.to_f}
 
  #convert to radians
  lat_radians=(lat/180) * Math::PI
  lng_radians=(lng/180) * Math::PI

  # 3963 is the earth's radius, more or less, in miles.
  # Which means that the distances you get out of this are in miles.
  # Want a different measure? Kilometers=6378. Nautical miles=3444. Furlongs=29544
  earths_radius = 3963
  table_name=City.table_name
  distance_sql=<<-SQL_END  (acos(cos(#{lat_radians})*cos(#{lng_radians})*
cos(radians(#{table_name}.latitude))*cos(radians(#{table_name}.longitude)) +
cos(#{lat_radians})*sin(#{lng_radians})*cos(radians(#{table_name}.latitude))*
sin(radians(#{table_name}.longitude)) +
sin(#{lat_radians})*sin(radians(#{table_name}.latitude))) * #{earths_radius})
  SQL_END

  cities = City.find(:all,
        :select=>"*, #{distance_sql} as distance",
        :order => 'distance asc',
        :limit => 10)
       
  render :text=>cities.collect{|c|c.attributes}.to_json
end
The key thing is the distance_sql, which does all the heavy lifting. You can take this basic formula and use it verbatim for any model with latitude/longitude columns -- just make sure you change the table_name to match your model.

Find within Radius

So, what if you want to constrain the results to a given radius? No problem. This finds all cities within a 25 mile radius:
  cities = City.find(:all,
        :select=>"*, #{distance_sql} as distance",
:conditions=>"#{distance_sql} <= 25",
        :order => 'distance asc')
Note that when you use distance in :conditions, you have to repeat distance_sql, whereas if you use distance in your order clause, you can simply reference the alias ("distance") which you gave the computed column in the select clause.

Utilizing that "distance" column

In the :select clause, you tacked an extra column -- distance -- on there. You can access this field just as you would any other (say from your .rhtml template): <%=city.name%> is <%=city.distance%> miles away.. Note that any of these add-on columns are treated by default as strings. If you want to format it as an actual number, you'll need to do something like <%=city.distance.to_f.ceil%> miles

New Java-based Mobile Gmail

Nov 02 by Andre in Google »

Google is doing a spectacular job building Java-based mobile apps for my phone. I just downloaded the new Gmail app for my Samsung A900. Installation is very, very, easy -- I just pointed my phone's browser to gmail.com/app, and Google correctly detected my phone brand/model.

Using the app feels a lot like using the Ajax-ified Gmail site (aside: have you tried the non-ajax version of Gmail? They must maintain a significantly different code base for it). For example, it provides as-you-type filtering of names/email addresses when you address an email.

Google's mobile apps are shaping up to be the only ones I use on my phone. While the Gmail app isn't quite as groundbreaking as Google Maps Mobile, it's still solid.