fusion_tables 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -16,7 +16,6 @@ tmtags
16
16
  ## PROJECT::GENERAL
17
17
  coverage
18
18
  rdoc
19
- pkg
20
19
 
21
20
  ## PROJECT::TEST
22
21
  test/test_config.yml
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Simon Tokumine
1
+ Copyright (c) 2010 Tom Verbeure, Simon Tokumine
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,63 +1,81 @@
1
1
  h1. fusion-tables
2
2
 
3
- This API lets you easily interact with Google Fusion Tables from your Ruby application.
3
+ This gem lets you easily interact with Google Fusion Tables from your Ruby application. Here are some "example maps and charts":http://www.tokumine.com/2010/08/10/fusion-tables-gem/.
4
+
5
+ h2. Gem Dependencies
6
+
7
+ * gdata >= 1.1.1
4
8
 
5
9
  h2. Installation
6
10
 
7
- gem install fusion-tables
11
+ bc. gem install fusion_tables
12
+
13
+ h2. To Use
14
+
15
+ bc. require 'fusion_tables'
16
+
17
+ or in Rails 2.3.x
18
+
19
+ bc. config.gem 'fusion_tables'
8
20
 
9
21
  h2. API examples
10
22
 
11
- The best place to see what's going on is in the tests, but this is a good starting point.
23
+ The best place to see examples (including uploading KML) is in the tests, but this is a good starting point.
12
24
 
13
- <pre><code>
14
- # Connect to service
25
+ <pre><code># Connect to service
15
26
  @ft = GData::Client::FusionTables.new
16
27
  @ft.clientlogin(username, password)
17
28
 
18
- # Create a new table
19
- # Configure the columns you want
20
- cols = [{:name => "friend name", :datatype => 'string' },
21
- {:name => "age", :datatype => 'number' },
22
- {:name => "meeting time", :datatype => 'datetime' },
23
- {:name => "where", :datatype => 'location' }]
24
-
25
- # Create the table
26
- @table = @ft.create_table "My upcoming meetings", cols
27
- @table.id #=> 42342 (the table's google id)
28
-
29
- # Insert data
30
- data = [{"friend name" => "Eric Wimp",
31
- "age" => 25,
32
- "meeting time" => Time.utc(2010,"aug",10,20,15,1),
33
- "where" => "29 Acacia Road, Nuttytown"]
29
+ # Browse existing tables
30
+ @ft.show_tables
31
+ # => [table_1, table_2]
34
32
 
35
- @table.insert data
36
-
37
- # Note - the insert method chunks the data array into 500 row chunks
33
+ # Getting table id suitable for using with google maps (see more below)
34
+ table_1.id #=> 42342 (the table's google id)
38
35
 
39
36
  # Count data
40
- @table.count #=> 1
37
+ table_1.count #=> 1
41
38
 
42
39
  # Select data
43
- @table.select #=> data
44
- row_ids = @table.select "ROWID"
40
+ table_1.select
41
+ #=> data
45
42
 
46
- # Update data (not working)
47
- # @table.update row_id, {:age => 26}
43
+ # Select data with conditions
44
+ table_1.select "name", "WHERE x=n"
45
+ #=> data
48
46
 
49
- # Delete data
50
- @table.delete row_id
47
+ # Select ROWIDs
48
+ row_ids = table_1.select "ROWID"
51
49
 
52
50
  # Drop tables
53
- @ft.drop @table.id # table id
54
- @ft.drop [@table1.id, @table2.id] # arrays of table ids
55
- @ft.drop /yacht/ # regex
51
+ @ft.drop table_1.id # table id
52
+ @ft.drop [table_1.id, table_2.id] # arrays of table ids
53
+ @ft.drop /yacht/ # regex on table name
54
+
55
+ # Creating a table
56
+ cols = [{:name => "friend name", :type => 'string' },
57
+ {:name => "age", :type => 'number' },
58
+ {:name => "meeting time", :type => 'datetime' },
59
+ {:name => "where", :type => 'location' }]
60
+
61
+ new_table = @ft.create_table "My upcoming meetings", cols
62
+
63
+ # Inserting rows (auto chunks every 500)
64
+ data = [{"friend name" => "Eric Wimp",
65
+ "age" => 25,
66
+ "meeting time" => Time.utc(2010,"aug",10,20,15,1),
67
+ "where" => "29 Acacia Road, Nuttytown"}]
68
+ new_table.insert data
69
+
70
+ # Delete row
71
+ new_table.delete row_id
56
72
  </code></pre>
57
73
 
58
74
  h2. Fusion Tables secret Geospatial Sauce
59
75
 
60
- Fusion Tables is a labs product from Google. You can "read more here":http://tables.googlelabs.com/, but the key thing is that it gives you *access to the google tile mill for ultra-fast generating of custom google map layers across massive datasets*
76
+ *"Geolocated Tweets example":http://tables.googlelabs.com/DataSource?snapid=73106*
77
+
78
+ Fusion Tables is a labs product from Google. You can "read more here":http://tables.googlelabs.com/, but the key thing is that it gives you *access to the google tile mill for fast generation of google map layers across large datasets*
61
79
 
62
80
  Fusion Tables supports the following geometry types:
63
81
 
@@ -65,13 +83,11 @@ Fusion Tables supports the following geometry types:
65
83
  * addresses (automatically geocodes them for you)
66
84
  * KML (point, polyline, polygon, multipolygon)
67
85
 
68
- h2. Thousands of geometries rendered in near real time, integrated with google maps v3
86
+ h2. Integrate with google maps v3
69
87
 
70
88
  Adding a fusion tables datalayer with many points/polygons to your v3 map is as simple as:
71
89
 
72
- <pre><code>
73
- layer = new google.maps.FusionTablesLayer(139529);
74
- </code></pre>
90
+ bc. layer = new google.maps.FusionTablesLayer(139529);
75
91
 
76
92
  That's it
77
93
 
@@ -95,10 +111,9 @@ You can also export your data (filtered and geocoded) to KML. As an example, her
95
111
 
96
112
  read "more here":http://code.google.com/apis/maps/documentation/javascript/overlays.html#FusionTables
97
113
 
98
- h2. A word of warning...
114
+ h2. A few words of warning...
99
115
 
100
- # Google has a recent habit of deleting projects. This is still a labs project, and may disappear at any time
101
- # The API is still very young and *will change*
116
+ # The API is still very young and *will probably change*
102
117
  # Currently you have to make a table public before you can display it on a map, unfortunately, this can only be done on the web interface. A suggested workaround is to put all your data in 1 big public table, and then query for the data you want to display based off a key/flag column
103
118
 
104
119
  h2. Note on Patches/Pull Requests
@@ -115,7 +130,7 @@ h2. Copyright
115
130
 
116
131
  Largely based on Tom Verbeure's work for MTBGuru: http://code.google.com/p/mtbguru-fusiontables/
117
132
 
118
- Copyright (c) 2010 Simon Tokumine. See LICENSE for details.
133
+ Copyright (c) 2010 Tom Verbeure, Simon Tokumine. See LICENSE for details.
119
134
 
120
135
 
121
136
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -0,0 +1,142 @@
1
+ #!/usr/local/bin/ruby
2
+ #
3
+ # Twitter Fusion Tables Mashup
4
+ # S.Tokumine 2010
5
+ #
6
+ # looks for tweets in the live stream around certain
7
+ # cities and posts them to fusion tables with KML attached
8
+ #
9
+ # Gem dependencies:
10
+ #
11
+ # tweetstream
12
+ # GeoRuby
13
+ # fusion_tables
14
+ #
15
+ # Output from running this for an evening
16
+ # http://tables.googlelabs.com/DataSource?snapid=72509
17
+ #
18
+ require 'rubygems'
19
+ require 'tweetstream'
20
+ require 'geo_ruby'
21
+ include GeoRuby
22
+ include SimpleFeatures
23
+ require 'fusion_tables'
24
+ require 'time'
25
+
26
+ class Object
27
+ def try(method, *args, &block)
28
+ send(method, *args, &block)
29
+ end
30
+ end
31
+
32
+ # Configure settings
33
+ config = YAML::load_file(File.join(File.dirname(__FILE__), 'credentials.yml'))
34
+ DEFAULT_SRID = 4328
35
+
36
+ # Twitter places
37
+ places = {
38
+ :san_francisco => [-122.75,36.8,-121.75,37.8],
39
+ :new_york => [-74,40,-73,41],
40
+ :tokyo => [139.3,35,140.3,36],
41
+ :london => [-0.54,51.2,0.46,52.2],
42
+ :madrid => [-4.2,40,-3.2,41],
43
+ :paris => [1.75,48.5,2.75, 49.5],
44
+ :beijing => [115.9,39,116.9,40],
45
+ :mumbai => [72.75,18.88,73.75,19.88],
46
+ }
47
+
48
+ # Configure fusion tables
49
+ ft = GData::Client::FusionTables.new
50
+ ft.clientlogin(config["google_username"], config["google_password"])
51
+ table_name = "twitter_fusion"
52
+ cols = [
53
+ {:name => 'screen_name', :type => 'string'},
54
+ {:name => 'avatar', :type => 'string'},
55
+ {:name => 'text', :type => 'string'},
56
+ {:name => 'created', :type => 'datetime'},
57
+ {:name => 'url', :type => 'string'},
58
+ {:name => 'location', :type => 'location'},
59
+ {:name => 'iso', :type => 'location'},
60
+ {:name => 'country_name', :type => 'location'},
61
+ {:name => 'city', :type => 'string'}
62
+ ]
63
+
64
+ # Create FT if it doesn't exist
65
+ tables = ft.show_tables
66
+ table = tables.select{|t| t.name == table_name}.first
67
+ table = ft.create_table(table_name, cols) if !table
68
+
69
+ # Configure Twitter stream client
70
+ data = []
71
+ tw = TweetStream::Client.new(config["twitter_username"],config["twitter_password"])
72
+
73
+ # configure friendly rate limit handling
74
+ tw.on_limit do |skip_count|
75
+ sleep 5
76
+ end
77
+
78
+ # start searching twitter stream and posting to FT
79
+ tw.filter(:locations => places.values.join(",")) do |tweet|
80
+ begin
81
+
82
+ country = "unknown"
83
+ iso = "unknown"
84
+ begin
85
+ country = tweet.try(:[],:place).try(:[], :country)
86
+ iso = tweet.try(:[],:place).try(:[], :country_code)
87
+ rescue
88
+ end
89
+
90
+ # Divine the tweets geometry
91
+ #
92
+ # overly complex due to
93
+ # * some US tweets have their lat/longs flipped (but not all...)
94
+ # * some geo tweets are made using a "place" envelope rather than exact lat/kng
95
+ if tweet[:geo]
96
+ if iso == 'US' && tweet[:geo][:coordinates][1] > 0
97
+ p = Point.from_x_y(tweet[:geo][:coordinates][0],tweet[:geo][:coordinates][1])
98
+ else
99
+ p = Point.from_x_y(tweet[:geo][:coordinates][1],tweet[:geo][:coordinates][0])
100
+ end
101
+ else
102
+ p = Polygon.from_coordinates(tweet[:place][:bounding_box][:coordinates]).envelope.center
103
+ end
104
+
105
+ # work out which city the tweet is from by testing with an extended bounding box
106
+ # BBox extention needed as twitter returns things outside our defined bboxes...
107
+ city = "unknown"
108
+ places.each do |key, value|
109
+ if !(p.x < value[0]-1 || p.x > value[2]+1 || p.y < value[1]-1 || p.y > value[3]+1)
110
+ city = key.to_s.gsub("_"," ")
111
+ break
112
+ end
113
+ end
114
+
115
+ # pack data
116
+ data << {
117
+ "screen_name" => tweet[:user][:screen_name],
118
+ "avatar" => tweet[:user][:profile_image_url],
119
+ "text" => tweet[:text],
120
+ "created" => Time.parse(tweet[:created_at]),
121
+ "url" => "http://twitter.com/#{tweet[:user][:screen_name]}/status/#{tweet[:id]}",
122
+ "location" => p.as_kml,
123
+ "iso" => iso,
124
+ "country_name" => country,
125
+ "city" => city
126
+ }
127
+ rescue => e
128
+ puts "ERROR: #{e.inspect}, #{e.backtrace}"
129
+ #let sleeping dogs lie...
130
+ end
131
+
132
+ # let us know how we're doing
133
+ puts "#{50-data.size}: #{city}, #{tweet.text}"
134
+
135
+ # Post to fusion tables
136
+ if data.size == 50
137
+ puts "sending data to fusion tables..."
138
+ ft_data = data
139
+ data = []
140
+ table.insert ft_data
141
+ end
142
+ end
@@ -0,0 +1,4 @@
1
+ twitter_username: your_username
2
+ twitter_password: your_password
3
+ google_username: your_username
4
+ google_password: your_password
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{fusion_tables}
8
- s.version = "0.1.0"
8
+ s.version = "0.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Simon Tokumine", "Tom Verbeure"]
12
- s.date = %q{2010-08-10}
12
+ s.date = %q{2010-08-12}
13
13
  s.description = %q{A simple Google Fusion Tables API wrapper. Supports bulk inserts and most API functions}
14
14
  s.email = %q{simon@tinypla.net}
15
15
  s.extra_rdoc_files = [
@@ -25,12 +25,16 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "TODO",
27
27
  "VERSION",
28
+ "examples/compare_tweets.rb",
29
+ "examples/credentials.example.yml",
28
30
  "fusion_tables.gemspec",
29
31
  "lib/fusion_tables.rb",
30
32
  "lib/fusion_tables/client/fusion_tables.rb",
31
33
  "lib/fusion_tables/data/data.rb",
32
34
  "lib/fusion_tables/data/table.rb",
33
35
  "lib/fusion_tables/ext/fusion_tables.rb",
36
+ "pkg/fusion_tables-0.1.0.gem",
37
+ "pkg/fusion_tables-0.1.1.gem",
34
38
  "test/README",
35
39
  "test/helper.rb",
36
40
  "test/test_client.rb",
@@ -47,7 +51,8 @@ Gem::Specification.new do |s|
47
51
  "test/helper.rb",
48
52
  "test/test_client.rb",
49
53
  "test/test_ext.rb",
50
- "test/test_table.rb"
54
+ "test/test_table.rb",
55
+ "examples/compare_tweets.rb"
51
56
  ]
52
57
 
53
58
  if s.respond_to? :specification_version then
@@ -114,11 +114,11 @@ module GData
114
114
  data.inject([]) do |ar,h|
115
115
  ret = {}
116
116
  h.each do |key, value|
117
- ret[key] = case get_datatype(key)
118
- when "number" then "#{value}"
119
- when "datetime" then "'#{value.strftime("%m-%d-%Y")}'"
120
- else "'#{value.gsub(/\\/, '\&\&').gsub(/'/, "''")}'"
121
- end
117
+ ret["'#{key.to_s}'"] = case get_datatype(key)
118
+ when "number" then "#{value}"
119
+ when "datetime" then "'#{value.strftime("%m-%d-%Y")}'"
120
+ else "'#{value.gsub(/\\/, '\&\&').gsub(/'/, "''")}'"
121
+ end
122
122
  end
123
123
  ar << ret
124
124
  ar
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusion_tables
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Simon Tokumine
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-08-10 00:00:00 +01:00
19
+ date: 2010-08-12 00:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -67,12 +67,16 @@ files:
67
67
  - Rakefile
68
68
  - TODO
69
69
  - VERSION
70
+ - examples/compare_tweets.rb
71
+ - examples/credentials.example.yml
70
72
  - fusion_tables.gemspec
71
73
  - lib/fusion_tables.rb
72
74
  - lib/fusion_tables/client/fusion_tables.rb
73
75
  - lib/fusion_tables/data/data.rb
74
76
  - lib/fusion_tables/data/table.rb
75
77
  - lib/fusion_tables/ext/fusion_tables.rb
78
+ - pkg/fusion_tables-0.1.0.gem
79
+ - pkg/fusion_tables-0.1.1.gem
76
80
  - test/README
77
81
  - test/helper.rb
78
82
  - test/test_client.rb
@@ -118,3 +122,4 @@ test_files:
118
122
  - test/test_client.rb
119
123
  - test/test_ext.rb
120
124
  - test/test_table.rb
125
+ - examples/compare_tweets.rb