rgeo 0.1.18 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/History.rdoc +11 -0
  2. data/README.rdoc +17 -30
  3. data/Version +1 -1
  4. data/ext/geos_c_impl/factory.c +4 -9
  5. data/ext/geos_c_impl/factory.h +8 -8
  6. data/ext/geos_c_impl/geometry.c +19 -2
  7. data/ext/geos_c_impl/geometry_collection.c +1 -1
  8. data/ext/geos_c_impl/polygon.c +2 -2
  9. data/lib/active_record/connection_adapters/mysql2spatial_adapter.rb +8 -6
  10. data/lib/active_record/connection_adapters/mysqlspatial_adapter.rb +8 -6
  11. data/lib/rgeo/active_record/arel_modifications.rb +4 -0
  12. data/lib/rgeo/active_record/base_modifications.rb +37 -2
  13. data/lib/rgeo/active_record/mysql_common.rb +2 -2
  14. data/lib/rgeo/cartesian.rb +6 -22
  15. data/lib/rgeo/cartesian/analysis.rb +3 -0
  16. data/lib/rgeo/cartesian/bounding_box.rb +337 -0
  17. data/lib/rgeo/cartesian/feature_classes.rb +11 -11
  18. data/lib/rgeo/cartesian/feature_methods.rb +5 -0
  19. data/lib/rgeo/cartesian/interface.rb +21 -4
  20. data/lib/rgeo/features/geometry.rb +0 -15
  21. data/lib/rgeo/geography/interface.rb +33 -6
  22. data/lib/rgeo/geography/simple_mercator/feature_classes.rb +30 -17
  23. data/lib/rgeo/geography/simple_mercator/feature_methods.rb +1 -1
  24. data/lib/rgeo/geography/simple_spherical/feature_classes.rb +38 -11
  25. data/lib/rgeo/geos.rb +2 -0
  26. data/lib/rgeo/geos/factory.rb +37 -21
  27. data/lib/rgeo/geos/impl_additions.rb +20 -0
  28. data/lib/rgeo/geos/interface.rb +17 -8
  29. data/lib/rgeo/geos/zm_factory.rb +241 -0
  30. data/lib/rgeo/geos/zm_impl.rb +432 -0
  31. data/lib/rgeo/impl_helpers/basic_geometry_collection_methods.rb +39 -0
  32. data/lib/rgeo/impl_helpers/basic_geometry_methods.rb +0 -5
  33. data/lib/rgeo/impl_helpers/basic_line_string_methods.rb +10 -1
  34. data/lib/rgeo/impl_helpers/basic_point_methods.rb +1 -13
  35. data/lib/rgeo/impl_helpers/basic_polygon_methods.rb +10 -0
  36. data/tests/common/geometry_collection_tests.rb +16 -0
  37. data/tests/common/point_tests.rb +27 -1
  38. data/tests/geos/tc_point.rb +2 -0
  39. data/tests/geos/tc_zmfactory.rb +85 -0
  40. data/tests/simple_cartesian/tc_geometry_collection.rb +1 -0
  41. data/tests/simple_cartesian/tc_point.rb +2 -1
  42. data/tests/simple_mercator/tc_point.rb +2 -0
  43. data/tests/simple_spherical/tc_geometry_collection.rb +2 -0
  44. data/tests/simple_spherical/tc_point.rb +2 -1
  45. data/tests/tc_oneoff.rb +0 -1
  46. data/tests/wkrep/tc_wkb_generator.rb +4 -4
  47. data/tests/wkrep/tc_wkb_parser.rb +2 -2
  48. data/tests/wkrep/tc_wkt_generator.rb +4 -4
  49. data/tests/wkrep/tc_wkt_parser.rb +5 -5
  50. metadata +23 -3
@@ -42,12 +42,12 @@ module RGeo
42
42
 
43
43
 
44
44
  # Creates and returns a cartesian factory of the preferred
45
- # implementation.
45
+ # Cartesian implementation.
46
46
  #
47
47
  # The actual implementation returned depends on which ruby
48
48
  # interpreter is running and what libraries are available.
49
49
  # RGeo will try to provide a fully-functional and performant
50
- # implementation if possible. If not, the simple cartesian
50
+ # implementation if possible. If not, the simple Cartesian
51
51
  # implementation will be returned.
52
52
  #
53
53
  # The given options are passed to the factory's constructor.
@@ -64,8 +64,25 @@ module RGeo
64
64
  alias_method :factory, :preferred_factory
65
65
 
66
66
 
67
- # Returns a factory for the simple cartesian implementation.
68
- # This implementation is always available.
67
+ # Returns a factory for the simple Cartesian implementation. This
68
+ # implementation provides all SFS 1.1 types, and also allows Z and
69
+ # M coordinates. It does not depend on external libraries, and is
70
+ # thus always available, but it does not implement many of the more
71
+ # advanced geometric operations. These limitations are:
72
+ #
73
+ # * Relational operators such as Features::Geometry#intersects? are
74
+ # not implemented for most types.
75
+ # * Relational constructors such as Features::Geometry#union are
76
+ # not implemented for most types.
77
+ # * Buffer and convex hull calculations are not implemented for most
78
+ # types. Boundaries are available except for GeometryCollection.
79
+ # * Length calculations are available, but areas are not. Distances
80
+ # are available only between points.
81
+ # * Equality and simplicity evaluation are implemented for some but
82
+ # not all types.
83
+ # * Assertions for polygons and multipolygons are not implemented.
84
+ #
85
+ # Unimplemented operations will return nil if invoked.
69
86
  #
70
87
  # Options include:
71
88
  #
@@ -115,21 +115,6 @@ module RGeo
115
115
  end
116
116
 
117
117
 
118
- # Cast this geometry to the given type (which must be one of the
119
- # type modules in the Features module) and return the resulting
120
- # object. Returns nil if the cast fails because the types are not
121
- # compatible or the object does not satisfy the assertions for the
122
- # new type.
123
- #
124
- # Generally, this is only useful for casting general classes to
125
- # subclasses; e.g. a GeometryCollection to a MultiPoint, or a
126
- # LineString to a LinearRing.
127
-
128
- def cast(type_)
129
- raise Errors::MethodUnimplemented
130
- end
131
-
132
-
133
118
  # Returns true if this geometric object is objectively equivalent
134
119
  # to the given object.
135
120
 
@@ -44,13 +44,32 @@ module RGeo
44
44
  # Geographic features provided by this factory perform calculations
45
45
  # assuming a spherical earth. In other words, geodesics are treated
46
46
  # as great circle arcs, and size and geometric calculations are
47
- # treated accordingly. Distance and area calculations report results
48
- # in meters. This makes this implementation ideal for everyday
47
+ # treated accordingly. Distance calculations report results in
48
+ # meters. This makes this implementation ideal for everyday
49
49
  # calculations on the globe where accuracy within about 0.5 percent
50
50
  # is sufficient.
51
51
  #
52
- # Currently, this implementation is incomplete. Basic input/output
53
- # and a few geodesic functions are implemented, but many return nil.
52
+ # === Limitations
53
+ #
54
+ # This implementation does not implement many of the more advanced
55
+ # geometric operations. In particular:
56
+ #
57
+ # * Relational operators such as Features::Geometry#intersects? are
58
+ # not implemented for most types.
59
+ # * Relational constructors such as Features::Geometry#union are
60
+ # not implemented for most types.
61
+ # * Buffer, convex hull, and envelope calculations are not
62
+ # implemented for most types. Boundaries are available except for
63
+ # GeometryCollection.
64
+ # * Length calculations are available, but areas are not. Distances
65
+ # are available only between points.
66
+ # * Equality and simplicity evaluation are implemented for some but
67
+ # not all types.
68
+ # * Assertions for polygons and multipolygons are not implemented.
69
+ #
70
+ # Unimplemented operations will return nil if invoked.
71
+ #
72
+ # === SRID for simple_spherical
54
73
  #
55
74
  # Simple_spherical features report SRID=4326, indicating EPSG 4326
56
75
  # (i.e. the WGS84 spheroid and the lat/lon system commonly used by
@@ -72,7 +91,10 @@ module RGeo
72
91
  # than those generated by, e.g., PostGIS (unless you direct PostGIS
73
92
  # to use spherical geodesics).
74
93
  #
75
- # Options include:
94
+ # === Options
95
+ #
96
+ # You may use the following options when creating a simple_spherical
97
+ # factory:
76
98
  #
77
99
  # <tt>:lenient_multi_polygon_assertions</tt>::
78
100
  # If set to true, assertion checking on MultiPolygon is disabled.
@@ -119,6 +141,8 @@ module RGeo
119
141
  # Distance and area computations return results in meters, whereas
120
142
  # all coordinates are represented in degrees latitude and longitude.
121
143
  #
144
+ # === About the coordinate system
145
+ #
122
146
  # This is not a true projected spatial reference: point coordinates
123
147
  # are still represented in degrees latitude and longitude. However,
124
148
  # computations are done in the projected spatial reference. (That
@@ -149,7 +173,10 @@ module RGeo
149
173
  # visualization APIs, so we've decided to fudge on this in the
150
174
  # interest of being true to our expected application use cases.
151
175
  #
152
- # Options include:
176
+ # === Options
177
+ #
178
+ # You may use the following options when creating a simple_mercator
179
+ # factory:
153
180
  #
154
181
  # <tt>:lenient_multi_polygon_assertions</tt>::
155
182
  # If set to true, assertion checking on MultiPolygon is disabled.
@@ -46,8 +46,8 @@ module RGeo
46
46
 
47
47
  include ::RGeo::Features::Point
48
48
  include ::RGeo::ImplHelpers::BasicGeometryMethods
49
- include ::RGeo::Geography::SimpleMercator::GeometryMethods
50
49
  include ::RGeo::ImplHelpers::BasicPointMethods
50
+ include ::RGeo::Geography::SimpleMercator::GeometryMethods
51
51
 
52
52
 
53
53
  def _validate_geometry
@@ -70,17 +70,30 @@ module RGeo
70
70
  end
71
71
 
72
72
 
73
+ def canonical_x
74
+ x_ = @x % 360.0
75
+ x_ -= 360.0 if x_ >= 180.0
76
+ x_
77
+ end
78
+ alias_method :canonical_longitude, :canonical_x
79
+ alias_method :canonical_lon, :canonical_x
80
+
81
+
73
82
  def canonical_point
74
83
  if @x >= -180.0 && @x < 180.0
75
84
  self
76
85
  else
77
- x_ = @x % 360.0
78
- x_ -= 360.0 if x_ >= 180.0
79
- PointImpl.new(@factory, x_, @y)
86
+ PointImpl.new(@factory, canonical_x, @y)
80
87
  end
81
88
  end
82
89
 
83
90
 
91
+ alias_method :longitude, :x
92
+ alias_method :lon, :x
93
+ alias_method :latitude, :y
94
+ alias_method :lat, :y
95
+
96
+
84
97
  end
85
98
 
86
99
 
@@ -89,10 +102,10 @@ module RGeo
89
102
 
90
103
  include ::RGeo::Features::LineString
91
104
  include ::RGeo::ImplHelpers::BasicGeometryMethods
105
+ include ::RGeo::ImplHelpers::BasicLineStringMethods
92
106
  include ::RGeo::Geography::SimpleMercator::GeometryMethods
93
107
  include ::RGeo::Geography::SimpleMercator::NCurveMethods
94
108
  include ::RGeo::Geography::SimpleMercator::CurveMethods
95
- include ::RGeo::ImplHelpers::BasicLineStringMethods
96
109
  include ::RGeo::Geography::SimpleMercator::LineStringMethods
97
110
 
98
111
 
@@ -109,12 +122,12 @@ module RGeo
109
122
 
110
123
  include ::RGeo::Features::Line
111
124
  include ::RGeo::ImplHelpers::BasicGeometryMethods
125
+ include ::RGeo::ImplHelpers::BasicLineStringMethods
126
+ include ::RGeo::ImplHelpers::BasicLinearRingMethods
112
127
  include ::RGeo::Geography::SimpleMercator::GeometryMethods
113
128
  include ::RGeo::Geography::SimpleMercator::NCurveMethods
114
129
  include ::RGeo::Geography::SimpleMercator::CurveMethods
115
- include ::RGeo::ImplHelpers::BasicLineStringMethods
116
130
  include ::RGeo::Geography::SimpleMercator::LineStringMethods
117
- include ::RGeo::ImplHelpers::BasicLinearRingMethods
118
131
 
119
132
 
120
133
  def _make_projection(projection_factory_) # :nodoc:
@@ -130,12 +143,12 @@ module RGeo
130
143
 
131
144
  include ::RGeo::Features::Line
132
145
  include ::RGeo::ImplHelpers::BasicGeometryMethods
146
+ include ::RGeo::ImplHelpers::BasicLineStringMethods
147
+ include ::RGeo::ImplHelpers::BasicLineMethods
133
148
  include ::RGeo::Geography::SimpleMercator::GeometryMethods
134
149
  include ::RGeo::Geography::SimpleMercator::NCurveMethods
135
150
  include ::RGeo::Geography::SimpleMercator::CurveMethods
136
- include ::RGeo::ImplHelpers::BasicLineStringMethods
137
151
  include ::RGeo::Geography::SimpleMercator::LineStringMethods
138
- include ::RGeo::ImplHelpers::BasicLineMethods
139
152
 
140
153
 
141
154
  def _make_projection(projection_factory_) # :nodoc:
@@ -151,10 +164,10 @@ module RGeo
151
164
 
152
165
  include ::RGeo::Features::Polygon
153
166
  include ::RGeo::ImplHelpers::BasicGeometryMethods
167
+ include ::RGeo::ImplHelpers::BasicPolygonMethods
154
168
  include ::RGeo::Geography::SimpleMercator::GeometryMethods
155
169
  include ::RGeo::Geography::SimpleMercator::NSurfaceMethods
156
170
  include ::RGeo::Geography::SimpleMercator::SurfaceMethods
157
- include ::RGeo::ImplHelpers::BasicPolygonMethods
158
171
 
159
172
 
160
173
  def _validate_geometry
@@ -179,8 +192,8 @@ module RGeo
179
192
 
180
193
  include ::RGeo::Features::GeometryCollection
181
194
  include ::RGeo::ImplHelpers::BasicGeometryMethods
182
- include ::RGeo::Geography::SimpleMercator::GeometryMethods
183
195
  include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
196
+ include ::RGeo::Geography::SimpleMercator::GeometryMethods
184
197
  include ::RGeo::Geography::SimpleMercator::GeometryCollectionMethods
185
198
 
186
199
 
@@ -197,10 +210,10 @@ module RGeo
197
210
 
198
211
  include ::RGeo::Features::GeometryCollection
199
212
  include ::RGeo::ImplHelpers::BasicGeometryMethods
200
- include ::RGeo::Geography::SimpleMercator::GeometryMethods
201
213
  include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
202
- include ::RGeo::Geography::SimpleMercator::GeometryCollectionMethods
203
214
  include ::RGeo::ImplHelpers::BasicMultiPointMethods
215
+ include ::RGeo::Geography::SimpleMercator::GeometryMethods
216
+ include ::RGeo::Geography::SimpleMercator::GeometryCollectionMethods
204
217
 
205
218
 
206
219
  def _make_projection(projection_factory_) # :nodoc:
@@ -216,11 +229,11 @@ module RGeo
216
229
 
217
230
  include ::RGeo::Features::GeometryCollection
218
231
  include ::RGeo::ImplHelpers::BasicGeometryMethods
232
+ include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
233
+ include ::RGeo::ImplHelpers::BasicMultiLineStringMethods
219
234
  include ::RGeo::Geography::SimpleMercator::GeometryMethods
220
235
  include ::RGeo::Geography::SimpleMercator::NCurveMethods
221
- include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
222
236
  include ::RGeo::Geography::SimpleMercator::GeometryCollectionMethods
223
- include ::RGeo::ImplHelpers::BasicMultiLineStringMethods
224
237
 
225
238
 
226
239
  def _make_projection(projection_factory_) # :nodoc:
@@ -236,11 +249,11 @@ module RGeo
236
249
 
237
250
  include ::RGeo::Features::GeometryCollection
238
251
  include ::RGeo::ImplHelpers::BasicGeometryMethods
252
+ include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
253
+ include ::RGeo::ImplHelpers::BasicMultiPolygonMethods
239
254
  include ::RGeo::Geography::SimpleMercator::GeometryMethods
240
255
  include ::RGeo::Geography::SimpleMercator::NSurfaceMethods
241
- include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
242
256
  include ::RGeo::Geography::SimpleMercator::GeometryCollectionMethods
243
- include ::RGeo::ImplHelpers::BasicMultiPolygonMethods
244
257
 
245
258
 
246
259
  def _validate_geometry
@@ -144,7 +144,7 @@ module RGeo
144
144
  end
145
145
 
146
146
 
147
- def convex_hull()
147
+ def convex_hull
148
148
  factory.unproject(projection.convex_hull)
149
149
  end
150
150
 
@@ -46,8 +46,8 @@ module RGeo
46
46
 
47
47
  include ::RGeo::Features::Point
48
48
  include ::RGeo::ImplHelpers::BasicGeometryMethods
49
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
50
49
  include ::RGeo::ImplHelpers::BasicPointMethods
50
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
51
51
 
52
52
 
53
53
  def _validate_geometry
@@ -75,6 +75,33 @@ module RGeo
75
75
  end
76
76
 
77
77
 
78
+ def equals?(rhs_)
79
+ return false unless rhs_.is_a?(self.class) && rhs_.factory == self.factory
80
+ case rhs_
81
+ when Features::Point
82
+ if @y == 90
83
+ rhs_.y == 90
84
+ elsif @y == -90
85
+ rhs_.y == -90
86
+ else
87
+ rhs_.x == @x && rhs_.y == @y
88
+ end
89
+ when Features::LineString
90
+ rhs_.num_points > 0 && rhs_.points.all?{ |elem_| equals?(elem_) }
91
+ when Features::GeometryCollection
92
+ rhs_.num_geometries > 0 && rhs_.all?{ |elem_| equals?(elem_) }
93
+ else
94
+ false
95
+ end
96
+ end
97
+
98
+
99
+ alias_method :longitude, :x
100
+ alias_method :lon, :x
101
+ alias_method :latitude, :y
102
+ alias_method :lat, :y
103
+
104
+
78
105
  end
79
106
 
80
107
 
@@ -83,8 +110,8 @@ module RGeo
83
110
 
84
111
  include ::RGeo::Features::LineString
85
112
  include ::RGeo::ImplHelpers::BasicGeometryMethods
86
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
87
113
  include ::RGeo::ImplHelpers::BasicLineStringMethods
114
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
88
115
  include ::RGeo::Geography::SimpleSpherical::LineStringMethods
89
116
 
90
117
 
@@ -96,10 +123,10 @@ module RGeo
96
123
 
97
124
  include ::RGeo::Features::Line
98
125
  include ::RGeo::ImplHelpers::BasicGeometryMethods
99
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
100
126
  include ::RGeo::ImplHelpers::BasicLineStringMethods
101
- include ::RGeo::Geography::SimpleSpherical::LineStringMethods
102
127
  include ::RGeo::ImplHelpers::BasicLineMethods
128
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
129
+ include ::RGeo::Geography::SimpleSpherical::LineStringMethods
103
130
 
104
131
 
105
132
  end
@@ -110,10 +137,10 @@ module RGeo
110
137
 
111
138
  include ::RGeo::Features::Line
112
139
  include ::RGeo::ImplHelpers::BasicGeometryMethods
113
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
114
140
  include ::RGeo::ImplHelpers::BasicLineStringMethods
115
- include ::RGeo::Geography::SimpleSpherical::LineStringMethods
116
141
  include ::RGeo::ImplHelpers::BasicLinearRingMethods
142
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
143
+ include ::RGeo::Geography::SimpleSpherical::LineStringMethods
117
144
 
118
145
 
119
146
  end
@@ -124,8 +151,8 @@ module RGeo
124
151
 
125
152
  include ::RGeo::Features::Polygon
126
153
  include ::RGeo::ImplHelpers::BasicGeometryMethods
127
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
128
154
  include ::RGeo::ImplHelpers::BasicPolygonMethods
155
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
129
156
 
130
157
 
131
158
  end
@@ -136,8 +163,8 @@ module RGeo
136
163
 
137
164
  include ::RGeo::Features::GeometryCollection
138
165
  include ::RGeo::ImplHelpers::BasicGeometryMethods
139
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
140
166
  include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
167
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
141
168
 
142
169
 
143
170
  end
@@ -148,9 +175,9 @@ module RGeo
148
175
 
149
176
  include ::RGeo::Features::GeometryCollection
150
177
  include ::RGeo::ImplHelpers::BasicGeometryMethods
151
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
152
178
  include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
153
179
  include ::RGeo::ImplHelpers::BasicMultiPointMethods
180
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
154
181
 
155
182
 
156
183
  end
@@ -161,9 +188,9 @@ module RGeo
161
188
 
162
189
  include ::RGeo::Features::GeometryCollection
163
190
  include ::RGeo::ImplHelpers::BasicGeometryMethods
164
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
165
191
  include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
166
192
  include ::RGeo::ImplHelpers::BasicMultiLineStringMethods
193
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
167
194
 
168
195
 
169
196
  end
@@ -174,9 +201,9 @@ module RGeo
174
201
 
175
202
  include ::RGeo::Features::GeometryCollection
176
203
  include ::RGeo::ImplHelpers::BasicGeometryMethods
177
- include ::RGeo::Geography::SimpleSpherical::GeometryMethods
178
204
  include ::RGeo::ImplHelpers::BasicGeometryCollectionMethods
179
205
  include ::RGeo::ImplHelpers::BasicMultiPolygonMethods
206
+ include ::RGeo::Geography::SimpleSpherical::GeometryMethods
180
207
 
181
208
 
182
209
  end
data/lib/rgeo/geos.rb CHANGED
@@ -73,3 +73,5 @@ require 'rgeo/geos/factory'
73
73
  require 'rgeo/geos/interface'
74
74
  require 'rgeo/geos/geos_c_impl'
75
75
  require 'rgeo/geos/impl_additions'
76
+ require 'rgeo/geos/zm_factory'
77
+ require 'rgeo/geos/zm_impl'
@@ -43,6 +43,7 @@ module RGeo
43
43
 
44
44
  class Factory
45
45
 
46
+
46
47
  include Features::Factory::Instance
47
48
 
48
49
 
@@ -65,7 +66,8 @@ module RGeo
65
66
  end
66
67
  buffer_resolution_ = opts_[:buffer_resolution].to_i
67
68
  buffer_resolution_ = 1 if buffer_resolution_ < 1
68
- _create(flags_, opts_[:srid].to_i, buffer_resolution_)
69
+ result_ = _create(flags_, opts_[:srid].to_i, buffer_resolution_)
70
+ result_
69
71
  end
70
72
  alias_method :new, :create
71
73
 
@@ -73,6 +75,19 @@ module RGeo
73
75
  end
74
76
 
75
77
 
78
+ def inspect # :nodoc:
79
+ "#<#{self.class}:0x#{object_id.to_s(16)} srid=#{_srid} bufres=#{_buffer_resolution} flags=#{_flags}>"
80
+ end
81
+
82
+
83
+ # Factory equivalence test.
84
+
85
+ def eql?(rhs_)
86
+ rhs_.is_a?(Factory) && rhs_.srid == _srid && rhs_._buffer_resolution == _buffer_resolution && rhs_._flags == _flags
87
+ end
88
+ alias_method :==, :eql?
89
+
90
+
76
91
  # Returns the SRID of geometries created by this factory.
77
92
 
78
93
  def srid
@@ -95,14 +110,6 @@ module RGeo
95
110
  end
96
111
 
97
112
 
98
- # Factory equivalence test.
99
-
100
- def eql?(rhs_)
101
- rhs_.is_a?(Factory) && rhs_.srid == _srid && rhs_._buffer_resolution == _buffer_resolution && rhs_._flags == _flags
102
- end
103
- alias_method :==, :eql?
104
-
105
-
106
113
  # See ::RGeo::Features::Factory#has_capability?
107
114
 
108
115
  def has_capability?(name_)
@@ -211,24 +218,33 @@ module RGeo
211
218
  return nil unless Geos.supported?
212
219
  keep_subtype_ = flags_[:keep_subtype]
213
220
  force_new_ = flags_[:force_new]
214
- if GeometryImpl === original_
215
- type_ = original_.geometry_type
216
- ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
217
- if original_.factory != self && ntype_ == type_
221
+ type_ = original_.geometry_type
222
+ ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
223
+ case original_
224
+ when GeometryImpl
225
+ # Optimization if we're just changing factories, but the
226
+ # factories are zm-compatible.
227
+ if original_.factory != self && ntype_ == type_ &&
228
+ original_.factory._flags & 0x6 == _flags & 0x6
229
+ then
218
230
  result_ = original_.dup
219
231
  result_._set_factory(self)
220
232
  return result_
221
233
  end
234
+ # LineString conversion optimization.
222
235
  if (original_.factory != self || ntype_ != type_) &&
223
- (type_ == Features::LineString || type_.include?(Features::LineString))
236
+ original_.factory._flags & 0x6 == _flags & 0x6 &&
237
+ type_.subtype_of?(Features::LineString) && ntype_.subtype_of?(Features::LineString)
224
238
  then
225
- if ntype_ == Features::LineString
226
- return LineStringImpl._copy_from(self, original_)
227
- elsif ntype_ == Features::Line
228
- return LineImpl._copy_from(self, original_)
229
- elsif ntype_ == Features::LinearRing
230
- return LinearRingImpl._copy_from(self, original_)
231
- end
239
+ return IMPL_CLASSES[ntype_]._copy_from(self, original_)
240
+ end
241
+ when ZMGeometryImpl
242
+ # Optimization for just removing a coordinate from an otherwise
243
+ # compatible factory
244
+ if _flags & 0x6 == 0x2 && self == original_.factory.z_factory
245
+ return Features.cast(original_.z_geometry, ntype_, flags_)
246
+ elsif _flags & 0x6 == 0x4 && self == original_.factory.m_factory
247
+ return Features.cast(original_.m_geometry, ntype_, flags_)
232
248
  end
233
249
  end
234
250
  false