rp_clustering-rgeo-activerecord 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MmJmOWM2NjZhMmMzODM1M2EyZDhkNjUyMzJjOGU1M2NlZTQ5N2IzOQ==
4
+ MzliYTdiMDQyNjMxZmQ3NGM4NGQyNTZmMjgwYmY4NDUyMTk0NGFiYQ==
5
5
  data.tar.gz: !binary |-
6
- NjZlZjdkMWNhNGYwOTdiMDU4YTdlNTIzODA2OGFmMDNhYjUyOTdkYg==
6
+ YTRmZWE4M2Q5NDhkZDE0NWYwOTEyYzRkYzk5MDU3ZmVmZDVlMDk2Mg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- Y2I1NTBjYzEyMTZmN2FjYTlmMDhjZDFlNGMxYjM0NWQxOTQ0ODUxMTYxMjBl
10
- YmI4MTgyNzAzYzhiMTYzZDFlYzAwZTgxNWQ2ZTJkN2RkNjg2NmYzN2M2ZWJh
11
- ODIyYTE0OTM0NzFlMzJkNTZhM2MxODc0ODZiOTNkNWFlYTNiYWU=
9
+ ODEwOGZjNWVmZDg3ODFkNTU5YjZlODQ0OGM5NjlkZTU2NTNkZWU5Mjg3NGIy
10
+ YzcxOWY5OGJjMzg4ZjJmODhhZWNkNDM2MjIzMGU0NTk4ZmM1NDE0MDdjNWYz
11
+ NTAwMjllZTRjMTY1MzRjNjI3NWUyZDQ3ODUxNjFiMGU5MjBhYTk=
12
12
  data.tar.gz: !binary |-
13
- NWFlODJlYWQ1Mzg2MjRmNTVlYzM0NTk0YmI3ZTQwMmY3MTlhNjE4NGVlNzQx
14
- YTZmZGJkMWFkOGVkM2Y5M2I4YzVlZDhhNDhiMjdhOGM4ZTEwNDdmNzUzYzEx
15
- ZDI2NDgyNTFjZmNjZTc5MjMyNDFlNTI2NjIxZjAxZDBjOWY4YzE=
13
+ NzQ1OTU4MWE4MDM3OWJkNTJkYWI0ZWQ2ZTkxN2Q1NTBhNjU1NWJmYTFiNWRm
14
+ NWRlMjUyN2I1NjExZjJiOWVhZTY1MjllZmQ0ZmViN2E4MmZhMjViOWQzMzFh
15
+ ODAzMzZlNjA3OGQ0ZWQ1YzczOTg1OTMwZjFkZjU2ZmM3MTNhYzM=
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # RPClustering::RGeo::ActiveRecord
2
2
 
3
+ [![Code Climate](https://codeclimate.com/github/robertpyke/rp_clustering-rgeo-activerecord.png)](https://codeclimate.com/github/robertpyke/rp_clustering-rgeo-activerecord)
4
+
3
5
  A RGeo PostGIS extension to provide Active Record (Model) clustering functionality.
4
6
 
5
7
  The intention is that this Gem will eventually provide abstracted methods for
@@ -8,7 +10,7 @@ both "on the fly" clustering, as well as cached clustering (including associated
8
10
  This Gem is currently in early development, so expect changes. On this note, if you'd like a specific clustering
9
11
  algorithm or feature added, please ask.
10
12
 
11
- If you find a problem with this Gem, please don't hesitate to raise an [issue](https://github.com/robertpyke/rp_clustering-rgeo-activerecord/issues).
13
+ If you find a problem with this Gem, please don't hesitate to [raise an issue](https://github.com/robertpyke/rp_clustering-rgeo-activerecord/issues).
12
14
 
13
15
  ## Installation
14
16
 
@@ -32,6 +34,98 @@ Or install it yourself as:
32
34
 
33
35
  ## Usage
34
36
 
37
+ ### Added in Version 0.0.3
38
+
39
+ This version allows for the "on the fly" use of a ST_SnapToGrid clustering function.
40
+ The function is added to ActiveRecord::Base (Models). The function is:
41
+
42
+ ```ruby
43
+
44
+ # Cluster using the PostGIS function ST_SnapToGrid
45
+ # -------------------------------------------------
46
+ #
47
+ # attr_to_cluster is the name of attribute to be clustered (a symbol).
48
+ # The attribute should be geometry attribute.
49
+ #
50
+ # Use the options Hash to define what cluster properties you would
51
+ # like returned.
52
+ #
53
+ # Options:
54
+ #
55
+ # [:grid_size] if set, will be used to create the cluster. The clustering
56
+ # works rougly like this; all geometries within 'grid_size'
57
+ # will be pulled together to form a single cluster. For a detailed
58
+ # explanation, please see the PostGIS docs for ST_SnapToGrid.
59
+ #
60
+ # If no +:grid_size+ is given, clusters will consist of all 'equal'
61
+ # geometries. E.g. all points at the same
62
+ # position (x,y) will be pulled together to form a single cluster.
63
+ # This is actually just a Group By of your +attr_to_cluster+.
64
+ #
65
+ # [:cluster_geometry_count] if set to true, the query will select, for
66
+ # each cluster, the number of geometries in the cluster.
67
+ #
68
+ # [:cluster_geometry_count_as] the name to select the
69
+ # cluster_geometry_count as, defaults to "cluster_geometry_count".
70
+ #
71
+ # [:cluster_centroid] if set to true, the query will select, for
72
+ # each cluster, the cluster centroid. The cluster_centroid returned
73
+ # will be a WKT string.
74
+ #
75
+ # [:cluster_centroid_as] the name to select the
76
+ # cluster_centroid as, defaults to "cluster_centroid".
77
+ #
78
+ # [:cluster_minimum_bounding_circle] if set to true, the query will select,
79
+ # for each cluster, the minimum bouding circle. The cluster_minimum_bounding_circle
80
+ # will be a WKT string.
81
+ #
82
+ # [:cluster_minimum_bounding_circle_as] the name to select the
83
+ # cluster_minimum_bounding_circle as, defaults to "cluster_minimum_bounding_circle"
84
+ #
85
+ # Note: Using the options hash, you must 'select' at least one attribute,
86
+ # else this method will rase an ArgumentError.
87
+
88
+ cluster_by_st_snap_to_grid(attr_to_cluster, options={})
89
+
90
+ ```
91
+
92
+ e.g.
93
+
94
+ ```ruby
95
+
96
+
97
+ @layer = Layer.find(params[:id])
98
+
99
+ cluster_result = @layer.cluster_by_st_snap_to_grid(
100
+ :geometry, # the column to cluster
101
+ grid_size: 0.01,
102
+ cluster_geometry_count: true,
103
+ cluster_centroid: true
104
+ )
105
+
106
+ features = []
107
+ cluster_result.each do |cluster|
108
+ geom_feature = Layer.rgeo_factory_for_column(:geometry).parse_wkt(cluster.cluster_centroid)
109
+ feature = RGeo::GeoJSON::Feature.new(geom_feature, nil, { cluster_size: cluster.cluster_geometry_count.to_i })
110
+
111
+ features << feature
112
+ end
113
+
114
+ feature_collection = RGeo::GeoJSON::FeatureCollection.new(features)
115
+ RGeo::GeoJSON.encode(feature_collection)
116
+
117
+ # BOOM! You just made some GeoJSON which is ready to be displayed on a map.
118
+ # You've also embedded the cluster_size in the GeoJSON, so you can do some
119
+ # fancy client side interaction based on cluster size. For example, you could
120
+ # make outliers (small clusters) bright red, or you could vary the size of the
121
+ # cluster centroid based on the size of cluster.
122
+ #
123
+ # Ideally, you could vary your +grid_size+ based on the user's view port.
124
+ # For example, you could set it to fixed values based on the user's zoom level.
125
+ # You could dynamically generate it based on some fraction of the user's view port bbox.
126
+
127
+ ```
128
+
35
129
  ### Added in Version 0.0.1
36
130
 
37
131
  This version allows for hand-coded low-level clustering via the Arel interface.
@@ -40,37 +134,37 @@ e.g.
40
134
 
41
135
  ```ruby
42
136
 
43
- # Get the Arel handle for the model
137
+ # Get the Arel handle for the model
44
138
 
45
- arel_table = MyModel.arel_table
139
+ arel_table = MyModel.arel_table
46
140
 
47
- # Our cluster grid size.
48
- # Smaller grid_size means more clusters.
49
- # Larger grid_size means less clusters (cluster covers a larger area).
50
- # See http://www.postgis.org/docs/ST_SnapToGrid.html for more info.
141
+ # Our cluster grid size.
142
+ # Smaller grid_size means more clusters.
143
+ # Larger grid_size means less clusters (cluster covers a larger area).
144
+ # See http://www.postgis.org/docs/ST_SnapToGrid.html for more info.
51
145
 
52
- grid_size = 0.1
146
+ grid_size = 0.1
53
147
 
54
- # Cluster against our model's :latlon attribute with a grid size of '0.1'.
55
- # Return the centroid of each cluster as "cluster_centroid".
148
+ # Cluster against our model's :latlon attribute with a grid size of '0.1'.
149
+ # Return the centroid of each cluster as "cluster_centroid".
56
150
 
57
- query = MyModel.select(
58
- arel_table.st_astext(
59
- arel_table.st_centroid(arel_table.st_collect(arel_table[:latlon]))
60
- ).as("cluster_centroid")
61
- ).group(arel_table[:latlon].st_snaptogrid(grid_size))
151
+ query = MyModel.select(
152
+ arel_table.st_astext(
153
+ arel_table.st_centroid(arel_table.st_collect(arel_table[:latlon]))
154
+ ).as("cluster_centroid")
155
+ ).group(arel_table[:latlon].st_snaptogrid(grid_size))
62
156
 
63
- # Iterate over our clusters
64
- query.all.each do |cluster|
157
+ # Iterate over our clusters
158
+ query.all.each do |cluster|
65
159
 
66
- # print the cluster_centroid (a point) as WKT
67
- puts cluster["cluster_centroid"]
160
+ # print the cluster_centroid (a point) as WKT
161
+ puts cluster["cluster_centroid"]
68
162
 
69
- # convert the WKT into a RGeo Geometry (a point)
70
- geographic_factory.parse_wkt(cluster["cluster_centroid")
163
+ # convert the WKT into a RGeo Geometry (a point)
164
+ geographic_factory.parse_wkt(cluster["cluster_centroid")
71
165
 
72
- # ...
73
- end
166
+ # ...
167
+ end
74
168
 
75
169
  ```
76
170
 
@@ -1,4 +1,5 @@
1
1
  require "rp_clustering-rgeo-activerecord/version"
2
+ require "rp_clustering-rgeo-activerecord/active_record_base_spatial_expressions"
2
3
  require "rp_clustering-rgeo-activerecord/arel_attribute_spatial_expressions"
3
4
  require "rp_clustering-rgeo-activerecord/arel_table_spatial_expressions"
4
5
 
@@ -8,12 +9,22 @@ module RPClustering
8
9
 
9
10
  module ActiveRecord
10
11
 
12
+ # Spatial Expressions to be attached directly to ActiveRecord::Base
13
+
14
+ module BaseSpatialExpressions
15
+ end
16
+
17
+ # Attach our Spatial Expression methods onto the ActiveRecord::Base class (as class methods).
18
+ class ::ActiveRecord::Base
19
+ include ::RPClustering::RGeo::ActiveRecord::BaseSpatialExpressions
20
+ end
21
+
11
22
  # Spatial Expressions to be attached directly to Arel Attributes (DB columns)
12
23
 
13
24
  module ArelAttributeSpatialExpressions
14
25
  end
15
26
 
16
- # Attach our Spatial Expression methods onto the Arel::Attribute class.
27
+ # Attach our Spatial Expression methods onto the Arel::Attribute class (as instance methods).
17
28
  #
18
29
  # i.e. As stated in the RGeo::ActiveRecord docs.. Allow chaining of spatial expressions from attributes
19
30
 
@@ -26,7 +37,7 @@ module RPClustering
26
37
  module ArelTableSpatialExpressions
27
38
  end
28
39
 
29
- # Attach our Spatial Expression methods onto the Arel::Table class.
40
+ # Attach our Spatial Expression methods onto the Arel::Table class (as instance methods).
30
41
 
31
42
  ::Arel::Table.class_eval do
32
43
  include ::RPClustering::RGeo::ActiveRecord::ArelTableSpatialExpressions
@@ -0,0 +1,154 @@
1
+ # Author: Robert Pyke
2
+
3
+ module RPClustering
4
+
5
+ module RGeo
6
+
7
+ module ActiveRecord
8
+
9
+ module BaseSpatialExpressions
10
+
11
+ # Use ActiveSupport::Concern to seperate our
12
+ # class and instance methods for inclusion into ActiveRecord::Base
13
+ extend ActiveSupport::Concern
14
+
15
+ module ClassMethods
16
+
17
+ # Cluster using the PostGIS function ST_SnapToGrid
18
+ # -------------------------------------------------
19
+ #
20
+ # attr_to_cluster is the name of attribute to be clustered (a symbol).
21
+ # The attribute should be geometry attribute.
22
+ #
23
+ # Use the options Hash to define what cluster properties you would
24
+ # like returned.
25
+ #
26
+ # Options:
27
+ #
28
+ # [:grid_size] if set, will be used to create the cluster. The clustering
29
+ # works rougly like this; all geometries within 'grid_size'
30
+ # will be pulled together to form a single cluster. For a detailed
31
+ # explanation, please see the PostGIS docs for ST_SnapToGrid.
32
+ #
33
+ # If no +:grid_size+ is given, clusters will consist of all 'equal'
34
+ # geometries. E.g. all points at the same
35
+ # position (x,y) will be pulled together to form a single cluster.
36
+ # This is actually just a Group By of your +attr_to_cluster+.
37
+ #
38
+ # [:cluster_geometry_count] if set to true, the query will select, for
39
+ # each cluster, the number of geometries in the cluster.
40
+ #
41
+ # [:cluster_geometry_count_as] the name to select the
42
+ # cluster_geometry_count as, defaults to "cluster_geometry_count".
43
+ #
44
+ # [:cluster_centroid] if set to true, the query will select, for
45
+ # each cluster, the cluster centroid. The cluster_centroid returned
46
+ # will be a WKT string.
47
+ #
48
+ # [:cluster_centroid_as] the name to select the
49
+ # cluster_centroid as, defaults to "cluster_centroid".
50
+ #
51
+ # [:cluster_minimum_bounding_circle] if set to true, the query will select,
52
+ # for each cluster, the minimum bouding circle. The cluster_minimum_bounding_circle
53
+ # will be a WKT string.
54
+ #
55
+ # [:cluster_minimum_bounding_circle_as] the name to select the
56
+ # cluster_minimum_bounding_circle as, defaults to "cluster_minimum_bounding_circle"
57
+ #
58
+ # Note: Using the options hash, you must 'select' at least one attribute,
59
+ # else this method will raise an ArgumentError.
60
+ #
61
+
62
+ def cluster_by_st_snap_to_grid(attr_to_cluster, options={})
63
+ raise ArgumentError, "Invalid cluster_by_st_snap_to_grid options provided" unless _are_cluster_options_valid?(options)
64
+
65
+ grid_size = options[:grid_size]
66
+
67
+ arel_table = self.arel_table
68
+ arel_attr = arel_table[attr_to_cluster]
69
+
70
+ q = self
71
+
72
+ # Get the cluster geometry count (if asked to)
73
+ if options[:cluster_geometry_count]
74
+ cluster_geometry_count_as = options[:cluster_geometry_count_as] || "cluster_geometry_count"
75
+ q = q._select_cluster_geometry_count(attr_to_cluster, cluster_geometry_count_as)
76
+ end
77
+
78
+ if options[:cluster_centroid]
79
+ cluster_centroid_as = options[:cluster_centroid_as] || "cluster_centroid"
80
+ q = q._select_cluster_centroid_as_wkt(attr_to_cluster, cluster_centroid_as)
81
+ end
82
+
83
+ if options[:cluster_minimum_bounding_circle]
84
+ cluster_minimum_bounding_circle_as = options[:cluster_minimum_bounding_circle_as] || "cluster_minimum_bounding_circle"
85
+ q = q._select_cluster_minimum_bounding_circle_as_wkt(attr_to_cluster, cluster_minimum_bounding_circle_as)
86
+ end
87
+
88
+ if grid_size
89
+ q = q.group(arel_attr.st_snaptogrid(grid_size))
90
+ else
91
+ q = q.group(arel_attr)
92
+ end
93
+
94
+ q
95
+ end
96
+
97
+ # Ensure the user is selecting something, and that
98
+ # the grid size is either nil, or is a valid integer
99
+
100
+ def _are_cluster_options_valid?(options)
101
+ selecting_something = (
102
+ options[:cluster_geometry_count] or
103
+ options[:cluster_centroid] or
104
+ options[:cluster_minimum_bounding_circle]
105
+ )
106
+
107
+ grid_size_valid = (
108
+ options[:grid_size].nil? or
109
+ ( options[:grid_size].is_a? Numeric and options[:grid_size] >= 0 )
110
+ )
111
+
112
+ valid = selecting_something and grid_size_valid
113
+ end
114
+
115
+ # Select the cluster geometry count
116
+
117
+ def _select_cluster_geometry_count(attr_to_cluster, as)
118
+ arel_table = self.arel_table
119
+ arel_attr = arel_table[attr_to_cluster]
120
+
121
+ select(arel_attr.count().as(as))
122
+ end
123
+
124
+ # Select the cluster centroid as WKT.
125
+
126
+ def _select_cluster_centroid_as_wkt(attr_to_cluster, as)
127
+ arel_table = self.arel_table
128
+ arel_attr = arel_table[attr_to_cluster]
129
+
130
+ select(
131
+ arel_table.st_astext(
132
+ arel_attr.st_collect
133
+ ).as(as)
134
+ )
135
+ end
136
+
137
+ # Select the cluster minimum bounding circle as WKT.
138
+
139
+ def _select_cluster_minimum_bounding_circle_as_wkt(attr_to_cluster, as)
140
+ arel_table = self.arel_table
141
+ arel_attr = arel_table[attr_to_cluster]
142
+
143
+ select(
144
+ arel_table.st_astext(
145
+ arel_table.st_minimumboundingcircle(arel_attr.st_collect)
146
+ ).as(as)
147
+ )
148
+ end
149
+
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -67,17 +67,16 @@ module RPClustering
67
67
 
68
68
  def st_minimumboundingcircle(num_segs=nil)
69
69
  args = [self]
70
+ spatial_flags = [true, true]
71
+
70
72
  if num_segs
71
73
  args << num_segs.to_s
72
-
73
- ::RGeo::ActiveRecord::SpatialNamedFunction.new(
74
- 'ST_MinimumBoundingCircle', args, [true, true, false]
75
- )
76
- else
77
- ::RGeo::ActiveRecord::SpatialNamedFunction.new(
78
- 'ST_MinimumBoundingCircle', args, [true, true]
79
- )
74
+ spatial_flags << false
80
75
  end
76
+
77
+ ::RGeo::ActiveRecord::SpatialNamedFunction.new(
78
+ 'ST_MinimumBoundingCircle', args, spatial_flags
79
+ )
81
80
  end
82
81
 
83
82
  end
@@ -83,17 +83,16 @@ module RPClustering
83
83
 
84
84
  def st_minimumboundingcircle(g, num_segs=nil)
85
85
  args = [g]
86
+ spatial_flags = [true, true]
87
+
86
88
  if num_segs
87
89
  args << num_segs.to_s
88
-
89
- ::RGeo::ActiveRecord::SpatialNamedFunction.new(
90
- 'ST_MinimumBoundingCircle', args, [true, true, false]
91
- )
92
- else
93
- ::RGeo::ActiveRecord::SpatialNamedFunction.new(
94
- 'ST_MinimumBoundingCircle', args, [true, true]
95
- )
90
+ spatial_flags << false
96
91
  end
92
+
93
+ ::RGeo::ActiveRecord::SpatialNamedFunction.new(
94
+ 'ST_MinimumBoundingCircle', args, spatial_flags
95
+ )
97
96
  end
98
97
 
99
98
  end
@@ -1,7 +1,7 @@
1
1
  module RPClustering
2
2
  module RGeo
3
3
  module ActiveRecord
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,110 @@
1
+ require 'test/unit'
2
+ require 'rgeo/active_record/adapter_test_helper'
3
+ require 'rp_clustering-rgeo-activerecord'
4
+ require 'squeel'
5
+
6
+ module RPClustering
7
+ module RGeo
8
+ module ActiveRecord
9
+ module Tests
10
+ class MyUnitTest < Test::Unit::TestCase # :nodoc:
11
+
12
+ # Use the RGEO active record adapter test helper
13
+
14
+ DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database.yml'
15
+ OVERRIDE_DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database_local.yml'
16
+ include ::RGeo::ActiveRecord::AdapterTestHelper
17
+
18
+
19
+ define_test_methods do
20
+
21
+ def populate_ar_class(content_)
22
+ klass_ = create_ar_class
23
+ case content_
24
+ when :latlon_point
25
+ klass_.connection.create_table(:spatial_test) do |t_|
26
+ t_.column 'latlon', :point, :srid => 4326
27
+ end
28
+ end
29
+ klass_
30
+ end
31
+
32
+ def test_cluster_by_st_snap_to_grid_exists
33
+ arel_klass = populate_ar_class(:latlon_point)
34
+ assert(
35
+ arel_klass.methods.include?(:cluster_by_st_snap_to_grid),
36
+ "ActiveRecord::Base should now have a cluster_by_st_snap_to_grid function. " +
37
+ "Found:\n#{arel_klass.methods.sort}"
38
+ )
39
+ end
40
+
41
+ def test_cluster_by_st_snap_to_grid_should_exception_with_invalid_options
42
+ arel_klass = populate_ar_class(:latlon_point)
43
+
44
+ assert_raise(ArgumentError) do
45
+ res = arel_klass.cluster_by_st_snap_to_grid(:latlon, grid_size: 10)
46
+ end
47
+
48
+ assert_raise(ArgumentError) do
49
+ res = arel_klass.cluster_by_st_snap_to_grid(:latlon, grid_size: -12, cluster_geometry_count: true)
50
+ end
51
+
52
+ assert_raise(ArgumentError) do
53
+ res = arel_klass.cluster_by_st_snap_to_grid(:latlon, grid_size: "2", cluster_geometry_count: true)
54
+ end
55
+
56
+ assert_nothing_thrown do
57
+ res = arel_klass.cluster_by_st_snap_to_grid(:latlon, grid_size: 2, cluster_geometry_count: true)
58
+ end
59
+
60
+ assert_nothing_thrown do
61
+ res = arel_klass.cluster_by_st_snap_to_grid(:latlon, grid_size: 2, cluster_centroid: true)
62
+ end
63
+
64
+ assert_nothing_thrown do
65
+ res = arel_klass.cluster_by_st_snap_to_grid(:latlon, grid_size: 2, cluster_minimum_bounding_circle: true)
66
+ end
67
+
68
+ end
69
+
70
+ def test_clustering_with_a_sufficiently_large_grid_size_reduces_count
71
+ arel_klass = populate_ar_class(:latlon_point)
72
+
73
+ points_generated = 0
74
+ (-5..5).each do |lng|
75
+ (-5..5).each do |lat|
76
+ obj = arel_klass.new
77
+ obj.latlon = @geographic_factory.point(lng, lat)
78
+ obj.save!
79
+ points_generated+=1
80
+ end
81
+ end
82
+
83
+ res = arel_klass.cluster_by_st_snap_to_grid(:latlon, grid_size: 5, cluster_geometry_count: true)
84
+ clusters = res.all
85
+ total_clusters = clusters.count()
86
+
87
+ points_found_in_clusters = 0
88
+
89
+ res.all.each do |cluster|
90
+ points_found_in_clusters += cluster["cluster_geometry_count"].to_i
91
+ end
92
+
93
+ assert_equal(points_generated, points_found_in_clusters,
94
+ "The sum of the size of our clusters should equal the number of points in the table"
95
+ )
96
+
97
+ # We should have less clusters than we have points
98
+ assert(total_clusters < points_generated, "we should have less clusters than we have points")
99
+
100
+ # We should have more than 1 cluster with this size grid
101
+ assert(total_clusters > 1, "we should have more than 1 cluster with this grid size")
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
data/test/test_unit.rb CHANGED
@@ -141,6 +141,7 @@ module RPClustering
141
141
  end
142
142
 
143
143
  end
144
+
144
145
  end
145
146
  end
146
147
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rp_clustering-rgeo-activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Pyke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-02-28 00:00:00.000000000 Z
11
+ date: 2013-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -178,11 +178,13 @@ files:
178
178
  - README.md
179
179
  - Rakefile
180
180
  - lib/rp_clustering-rgeo-activerecord.rb
181
+ - lib/rp_clustering-rgeo-activerecord/active_record_base_spatial_expressions.rb
181
182
  - lib/rp_clustering-rgeo-activerecord/arel_attribute_spatial_expressions.rb
182
183
  - lib/rp_clustering-rgeo-activerecord/arel_table_spatial_expressions.rb
183
184
  - lib/rp_clustering-rgeo-activerecord/version.rb
184
185
  - rp_clustering-rgeo-activerecord.gemspec
185
186
  - test/database.yml
187
+ - test/test_clustering.rb
186
188
  - test/test_unit.rb
187
189
  homepage: https://github.com/robertpyke/rp_clustering-rgeo-activerecord
188
190
  licenses:
@@ -210,4 +212,6 @@ specification_version: 4
210
212
  summary: RGeo PostGIS extension to provide clustering functionality
211
213
  test_files:
212
214
  - test/database.yml
215
+ - test/test_clustering.rb
213
216
  - test/test_unit.rb
217
+ has_rdoc: