kingpin 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.markdown +230 -0
  2. data/VERSION +1 -1
  3. data/kingpin.gemspec +4 -4
  4. metadata +6 -6
  5. data/README.rdoc +0 -19
@@ -0,0 +1,230 @@
1
+ Kingpin
2
+ ========
3
+
4
+ Kingpin is a Ruby gem that provides seamless integration of [Pincaster](https://github.com/jedisct1/Pincaster) into every ActiveRecord model in Rails 2 and 3.
5
+
6
+ Pincaster is a very fast memory driven but persisting **NoSQL** (yeah..) DB engine for fast geolocation operations. Kingpin directly integrates Pincaster into every ActiveRecord model that has at least real or virtual attributes for latitude and longitude. After indexing all of your objects you can easily request objects around your query object. Kingpin therefore provides several methods as well as named scopes and perfectly maps all operations that usually had to be taken manually.
7
+
8
+ Pincaster supports different layers that can be used to distinguish the kind of objects to be stored. Kingpin automatically creates a layer per ActiveRecord model and uses the class name as layer name. Every indexed AR object then is provided with a related Pincaster object - in this scope called a 'pin'. These pins can be used for fast nearby retrieval as well as distance calculation.
9
+
10
+ Prerequisites
11
+ -------------
12
+
13
+ * Install Frank Denis's [Pincaster](https://github.com/jedisct1/Pincaster)
14
+ * Configure Pincaster according to your needs
15
+ * Choose a proper 'Accuracy' method in pincaster.conf / I recommend: 'rhomboid'
16
+ * Startup Pincaster
17
+
18
+ Installation
19
+ ------------
20
+
21
+ Kingpin is a gem available via [Rubygems.org](http://www.rubygems.org). To install it, simply put it into your Rails3 app's Gemfile:
22
+
23
+ gem 'kingpin', '0.x.0'
24
+
25
+ and afterwards run bundler:
26
+
27
+ bundle install
28
+
29
+ In case you are on Rails 2 without bundler support add Kingpin to your environment.rb as you are used to with other gems and install it via:
30
+
31
+ rake gems:install
32
+
33
+ or:
34
+
35
+ gem install kingpin
36
+
37
+ Congrats, you're done!
38
+
39
+
40
+ Configuration
41
+ -------------
42
+
43
+ Kingpin comes with it's own default configuration file that is loaded in case none is provided by the user. Create your own one at:
44
+
45
+ config/kingpin.yml
46
+
47
+ with YAML formatted content like that:
48
+
49
+ ---
50
+ protocol: http
51
+ host: localhost
52
+ port: 4269
53
+ namespace: '/api/1.0'
54
+
55
+ Do not forget the '- - -' and don't mess with spaces or tabs, it's [YAML](http://www.yaml.org). Adjust the values to your needs. Most recent versions of Pincaster support http only afaik, so you should not change it. Same with the namespace, changing it results in 404 responses for your requests.
56
+
57
+
58
+ Integration
59
+ -----------
60
+
61
+ Integration into you models is straight forward. Assuming that your model has an attribute_reader or accessor_method like one of the following:
62
+ [:latitude, :ltt, :ltd, :lat]
63
+
64
+ as well as one of the following for longitude:
65
+
66
+ [:longitude, :long, :lng, :lgt, :lgdt]
67
+
68
+ **and** the values are in *DEG* **not** *RAD*, your way of integration looks like that:
69
+
70
+ class FooWithLocation
71
+ pinnable
72
+ ...
73
+ end
74
+
75
+
76
+ Either way, Kingpin tries to minimize your pain, so some configuration options are provided as well:
77
+
78
+ * `:methods => {:lat => :your_latitude, :lng => :your_longitude}` in case your location accessors have different names
79
+ * `:rad => true` defaults to *false* if not mentioned, and assumes your lat and lng in *RAD* instead of *DEG*
80
+ * `:autopin => true` automatically generates a Pincaster record every time an instance of an enabled model is saved
81
+ * `:include => [unimplemented yet]`
82
+
83
+ Example: In case your longitude resides at :cool_longitude, your latitude at :cool_latitude, the values are stored in *RAD* and you would like to automatically create Pincaster pins, your classes head should look like this:
84
+
85
+ class FooWithLocation
86
+ pinnable :methods => { :lat => :cool_latitude, :lng => :cool_longitude }, :rad => true, :autopin => true
87
+ ...
88
+ end
89
+
90
+ Indexing
91
+ --------
92
+
93
+ Next you should create some pins. The most recent version of Kingpin does not provide a Raketask for that automatically, but it will in the next release. You could create one on your own and make it look like the following:
94
+
95
+
96
+ namespace :kingpin do
97
+ desc "Rebuild Pincaster index for FooWithLocations"
98
+ task :reindex_foo_with_locations => :environment do
99
+ if Pincaster.is_alive?
100
+ 1.upto(FooWithLocation.find(:last).id) do |i|
101
+ begin
102
+ STDOUT.print "indexed: " + i.to_s + "\r"
103
+ FooWithLocation.find(i).add_pin
104
+ STDOUT.flush
105
+ rescue
106
+ end
107
+ end
108
+ else
109
+ puts "Pincaster seems to be down!\n"
110
+ end
111
+ puts "Finished reindexing FooWithLocations.\n"
112
+ end
113
+ end
114
+
115
+ Invocation
116
+ ----------
117
+
118
+ Kingpin comes with some high- and some low-level operations you can use.
119
+
120
+ **Highlevel operations**
121
+
122
+ *Instance methods*
123
+
124
+ * nearby_ids(n,limit) - returns the id's of those foo's which are in range of n meters
125
+ * nearby(n,limit) - returns an array of fully fledged AR records within a range of n meters
126
+
127
+ Please have a look at the Pincaster doc's to fully understand how *limit* works. It's not supposed to work like the typical SQL like limit. If ommitted it defaults to 10000.
128
+
129
+ Example:
130
+
131
+ foo = FooWithLocation.find(4711)
132
+ foo.nearby_ids(500)
133
+
134
+ Example:
135
+
136
+ foo = FooWithLocation.find(42)
137
+ foo.nearby(500)
138
+
139
+ *Class methods - speak (named) scope*
140
+
141
+ * nearby(location, n)
142
+
143
+ nearby returns a named scope (sorry, no Rails3 scope available yet) that can be chained as you are used to.
144
+
145
+ Example:
146
+
147
+ foo = FooWithLocation.find(23)
148
+ FooWithLocation.nearby(foo, 500)
149
+
150
+ **Low level operations**
151
+
152
+ You would like to gain control over pins to be created? No problem. Kingpin provides the following instance methods for every enabled ActiveRecord model:
153
+
154
+ foo = FooWithLocation.find(23)
155
+
156
+ * `foo.add_pin` - adds a pin for self
157
+ * `foo.pin` - returns an existing pin for self or nil
158
+ * `foo.delete_pin!` - deletes an existing pin
159
+ * `foo.nearby_ids(radius, limit)` - returns an array of AR instance id's in given radius of self
160
+ * `foo.nearby(radius, limit)` - returns an array of AR objects in given radius of self
161
+ * `foo.pin_lat` - returns self's normalized latitude (in DEG)
162
+ * `foo.pin_lng` - returns self's normalized longitude (in DEG)
163
+
164
+ There are also some Pincaster related methods that are bound to a publicly available Pincaster class. These read as follows:
165
+
166
+ * `Pincaster.is_alive?` - returns *true* or *false*, depending on Pincaster server's state
167
+ * `Pincaster.shutdown!` - cleanly shut's down Pincaster, so every in-memory-only-data can be persited before exit
168
+ * `Pincaster.layers` - returns an array of strings representing the available layers (AR class names of indexed models)
169
+ * `Pincaster.has_layer(string)` - returns *true* or *false* depending of existance of the given layer
170
+ * `Pincaster.add_layer(string)` - adds a layer with given string as name
171
+ * `Pincaster.delete_layer!(string)` - deletes the layer with the given name
172
+ * `Pincaster.layer(string)` - return a Kingpin layer object that can be used to retrieve some more information about a layer
173
+ * `Pincaster.config` - returns a Kingpin config objects that hold's Pincasters config
174
+
175
+ Interesting layer related methods are:
176
+
177
+ layer = Pincaster.layer("FooWithLocation")
178
+
179
+ * `layer.name` - returns layers name
180
+ * `layer.records` - returns the number of records (pin's) in that very layer
181
+ * `layer.geo_records` - returns the number of records in that layer having geo data included
182
+ * `layer.distance_accuracy` - returns the distance accuracy level
183
+ * `layer.type` - returns the layers type (please have a look at the Pincaster doc's here)
184
+ * `layer.bounds` - returns the layers bounds
185
+
186
+ Coming soon
187
+ -----------
188
+
189
+ Kingpin is missing some functionality yet, but this will arrive soon:
190
+
191
+ - support for rectangle search
192
+ - support for storage of optional AR attributes of an instance via include
193
+ - distance integration into every returned AR record at retrieval time
194
+ - automated Raketask for index creation
195
+ - tests
196
+
197
+ Authors
198
+ -------
199
+
200
+ Kingpin was written by:
201
+
202
+ [Jan Roesner](http://railspotting.de) mailto: <jan@roesner.it>
203
+
204
+ for use at [Friendticker](http://www.friendticker.de)
205
+
206
+
207
+ Thanks
208
+ ------
209
+
210
+ * Frank Denis for his support
211
+ * Anke for moral support
212
+ * the Friendticker staff
213
+
214
+ Contributing to Kingpin
215
+ -----------------------
216
+
217
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
218
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
219
+ * Fork the project
220
+ * Start a feature/bugfix branch
221
+ * Commit and push until you are happy with your contribution
222
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
223
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
224
+ * Send me a pull request. Bonus points for topic branches.
225
+
226
+
227
+ Copyright
228
+ ---------
229
+
230
+ Copyright (c) 2011 Jan Roesner. See LICENSE.txt for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.6.1
@@ -5,16 +5,16 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{kingpin}
8
- s.version = "0.6.0"
8
+ s.version = "0.6.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jan Roesner"]
12
- s.date = %q{2011-03-11}
12
+ s.date = %q{2011-03-22}
13
13
  s.description = %q{Kingpin extends every ActiveRecord model to become a Pincaster pin automatically. Thus the model automatically creates a Pincaster pin everytime it is saved. Kingpin afterwards provides methods at class and instance level that make geolocation easy and thanks to Pincaster amazingly fast.}
14
14
  s.email = %q{jan@roesner.it}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
- "README.rdoc"
17
+ "README.markdown"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
  "Gemfile",
23
23
  "Gemfile.lock",
24
24
  "LICENSE.txt",
25
- "README.rdoc",
25
+ "README.markdown",
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "config/kingpin.yml",
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kingpin
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 0
10
- version: 0.6.0
9
+ - 1
10
+ version: 0.6.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jan Roesner
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-11 00:00:00 +01:00
18
+ date: 2011-03-22 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -88,14 +88,14 @@ extensions: []
88
88
 
89
89
  extra_rdoc_files:
90
90
  - LICENSE.txt
91
- - README.rdoc
91
+ - README.markdown
92
92
  files:
93
93
  - .document
94
94
  - .rspec
95
95
  - Gemfile
96
96
  - Gemfile.lock
97
97
  - LICENSE.txt
98
- - README.rdoc
98
+ - README.markdown
99
99
  - Rakefile
100
100
  - VERSION
101
101
  - config/kingpin.yml
@@ -1,19 +0,0 @@
1
- = kingpin
2
-
3
- Description goes here.
4
-
5
- == Contributing to kingpin
6
-
7
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
- * Fork the project
10
- * Start a feature/bugfix branch
11
- * Commit and push until you are happy with your contribution
12
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
-
15
- == Copyright
16
-
17
- Copyright (c) 2011 Jan Roesner. See LICENSE.txt for
18
- further details.
19
-