kingpin 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +230 -0
- data/VERSION +1 -1
- data/kingpin.gemspec +4 -4
- metadata +6 -6
- data/README.rdoc +0 -19
data/README.markdown
ADDED
@@ -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.
|
1
|
+
0.6.1
|
data/kingpin.gemspec
CHANGED
@@ -5,16 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{kingpin}
|
8
|
-
s.version = "0.6.
|
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-
|
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.
|
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.
|
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:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
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-
|
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.
|
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.
|
98
|
+
- README.markdown
|
99
99
|
- Rakefile
|
100
100
|
- VERSION
|
101
101
|
- config/kingpin.yml
|
data/README.rdoc
DELETED
@@ -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
|
-
|