Archive for October, 2007

Ruby on rails yahoo-geocoder

I recently was given a task which required some geocoding. Eventually the geocodes will find there way into a google map. The temptation with google maps is the geocode everything using googles built in geocoding. This is great for a couple of points. However if you are going to have many points you are better off caching the longitude and latitude for speedy marker sets.

in order to get yahoo-geocoder working you’ll want to install the gem

Gem install yahoo-geocode

After that simple step you will want to reboot any mongrel or webrick servers that are running to ensure that the new gem is loaded in your environment.

once installed you need to get a key from yahoo

you should be ready to go now. using the yahoo geocode api to cache latitude and longitude is as simple as this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require 'yahoo/geocode'
class Post < ActiveRecord::Base
	before_validation :fillfields
	validates_presence_of :latitude
	validates_presence_of :zipcode, :if=>:in_us?
	validates_presence_of :city
	def in_us?
		country=='US'
	end
	private
	def fillfields
		yg=Yahoo::Geocode.new "Your api id goes here"
		begin
			locations = yg.locate  self.zipcode+', '+self.city+', '+self.country
			self.longitude=locations.first.longitude
			self.latitude =locations.first.latitude
			self.city = locations.first.city
			self.country = locations.first.country
		rescue
			self.errors.add_to_base('Validation could not be done')
		end
	end
end

As you can see everything is nicely tucked away in the posts model. There are no changes to the views or controllers for this one. After that you can call:

Post.find(:all).to_json

or

Post.find(:all).to_xml

to start consuming the locations in google maps or any other mapping software for that matter.

Animator Class Enhancement

I don’t know how much exploration of the Animator class many people have done out there, but a current project seemed like a good place to experiment with it. I’m pretty impressed with Adobe’s implementation of it—though I’m far more impressed with the capabilities of E4X XML tools that make it possible—but some things are less then ready for prime-time.

Basically, flashes Animator.play()

Example

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

How it works

This Assumes the code is on frame 1 of the main timeline.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import fl.events.*;
import fl.motion.*;
 
//stage.frameRate = fps;
//trace(stage.frameRate);
stop();
 
 
/*************  this is the speed controller (or delay controller) *************/
var player:Timer = new Timer(33,30); // "33"/1000th of a second is pretty much 30 fps and the animation is "30" frames long
	player.addEventListener(TimerEvent.TIMER, playAnimator);
	player.start();
 
function playAnimator(e:TimerEvent)
{
	if(e.currentTarget.currentCount < 30){
		ner_animator.time = e.currentTarget.currentCount;
	}else{
		ner_animator.stop();
		ner_animator.rewind();
		player.reset();
		player.start();
	}
}
 
/************* speed controlled animator (taken straight from the clipboard but with the Animator.play() removed *************/
var ner_xml:XML = <motion duration="30" xmlns="fl.motion.*" xmlns:geom="flash.geom.*" xmlns:filters="flash.filters.*">
	<source>
		<source frameRate="10" x="95" y="114" scaleX="1" scaleY="1" rotation="0" elementType="movie clip" instanceName="ner" symbolName="Symbol 1">
			<dimensions>
				<geom:Rectangle left="0" top="0" width="42" height="42"/>
			</dimensions>
			<transformationPoint>
				<geom:Point x="0.5" y="0.5"/>
			</transformationPoint>
		</source>
	</source>
 
	<keyframe index="0" tweenSnap="true" tweenSync="true">
		<tweens>
			<simpleEase ease="0"/>
		</tweens>
	</keyframe>
 
	<keyframe index="29" tweenSync="true" x="253"/>
</motion>;
 
var ner_animator:Animator = new Animator(ner_xml, ner);
//ner_animator.play(); // removed because we play it with the new player function

So as you can see, it’s just replacing whatever the built in play() function does (likely some kind of onEnterFrame event) with a Timer driven, and thus framerate independent animation. Which allows old slow computers to keep things moving more like the Tween or Tweener class, frames will be skipped to keep the timing more or less on track (as much as possible).

I’m planning on releasing an class that extends the Animator class built into flash—or possibly building a new one from scratch—that will include this speed feature as well as other enhancements I’ve required in the last project (also coming soon).