Module: RGeo::Feature
- Defined in:
- lib/rgeo/feature/line.rb,
lib/rgeo/feature/curve.rb,
lib/rgeo/feature/point.rb,
lib/rgeo/feature/types.rb,
lib/rgeo/feature/factory.rb,
lib/rgeo/feature/polygon.rb,
lib/rgeo/feature/surface.rb,
lib/rgeo/feature/geometry.rb,
lib/rgeo/feature/line_string.rb,
lib/rgeo/feature/linear_ring.rb,
lib/rgeo/feature/multi_curve.rb,
lib/rgeo/feature/multi_point.rb,
lib/rgeo/feature/multi_polygon.rb,
lib/rgeo/feature/multi_surface.rb,
lib/rgeo/feature/factory_generator.rb,
lib/rgeo/feature/multi_line_string.rb,
lib/rgeo/feature/geometry_collection.rb,
ext/geos_c_impl/globals.c
Defined Under Namespace
Modules: Curve, Factory, FactoryGenerator, Geometry, GeometryCollection, Instance, Line, LineString, LinearRing, MultiCurve, MultiLineString, MultiPoint, MultiPolygon, MultiSurface, Point, Polygon, Surface, Type
Class Method Summary collapse
-
.cast(obj, *params) ⇒ Object
Cast the given object according to the given parameters, if possible, and return the resulting object.
Class Method Details
.cast(obj, *params) ⇒ Object
Cast the given object according to the given parameters, if possible, and return the resulting object. If the requested cast is not possible, nil is returned.
Parameters may be provided as a hash, or as separate arguments. Hash keys are as follows:
:factory
-
Set the factory to the given factory. If this argument is not given, the original object’s factory is kept.
:type
-
Cast to the given type, which must be a module in the RGeo::Feature namespace. If this argument is not given, the result keeps the same type as the original.
:project
-
If this is set to true, and both the original and new factories support proj4 projections, then the cast will also cause the coordinates to be transformed between those two projections. If set to false, the coordinates are not modified. Default is false.
:keep_subtype
-
Value must be a boolean indicating whether to keep the subtype of the original. If set to false, casting to a particular type always casts strictly to that type, even if the old type is a subtype of the new type. If set to true, the cast retains the subtype in that case. For example, casting a LinearRing to a LineString will normally yield a LineString, even though LinearRing is already a more specific subtype. If you set this value to true, the casted object will remain a LinearRing. Default is false.
:force_new
-
Always return a newly-created object, even if neither the type nor factory is modified. Normally, if this is set to false, and a cast is not set to modify either the factory or type, the original object itself is returned. Setting this flag to true causes cast to return a clone in that case. Default is false.
You may also pass the new factory, the new type, and the flags as separate arguments. In this case, the flag names must be passed as symbols, and their effect is the same as setting their values to true. You can even combine separate arguments and hash arguments. For example, the following three calls are equivalent:
RGeo::Feature.cast(geom, :type => RGeo::Feature::Point, :project => true)
RGeo::Feature.cast(geom, RGeo::Feature::Point, :project => true)
RGeo::Feature.cast(geom, RGeo::Feature::Point, :project)
RGeo provides a default casting algorithm. Individual feature implementation factories may override this and customize the casting behavior by defining the override_cast method. See RGeo::Feature::Factory#override_cast for more details.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/rgeo/feature/types.rb', line 158 def cast(obj, *params) # Interpret params factory = obj.factory type = obj.geometry_type opts = {} params.each do |param| case param when Factory::Instance opts[:factory] = param when Type opts[:type] = param when Symbol opts[param] = true when Hash opts.merge!(param) end end force_new = opts[:force_new] keep_subtype = opts[:keep_subtype] project = opts[:project] nfactory = opts.delete(:factory) || factory ntype = opts.delete(:type) || type # Let the factory override if nfactory.respond_to?(:override_cast) override = nfactory.override_cast(obj, ntype, opts) return override unless override == false end # Default algorithm ntype = type if keep_subtype && type.include?(ntype) if ntype == type # Types are the same if nfactory == factory force_new ? obj.dup : obj elsif type == Point z = factory.property(:has_z_coordinate) ? obj.z : nil coords = if project && (cs = factory.coord_sys) && (ncs = nfactory.coord_sys) cs.transform_coords(ncs, obj.x, obj.y, z) else [obj.x, obj.y] end coords << (z || 0.0) if nfactory.property(:has_z_coordinate) && coords.size < 3 m = factory.property(:has_m_coordinate) ? obj.m : nil coords << (m || 0.0) if nfactory.property(:has_m_coordinate) nfactory.point(*coords) elsif type == Line nfactory.line(cast(obj.start_point, nfactory, opts), cast(obj.end_point, nfactory, opts)) elsif type == LinearRing nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) elsif type == LineString nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) elsif type == Polygon nfactory.polygon( cast(obj.exterior_ring, nfactory, opts), obj.interior_rings.map { |r| cast(r, nfactory, opts) } ) elsif type == MultiPoint nfactory.multi_point(obj.map { |g| cast(g, nfactory, opts) }) elsif type == MultiLineString nfactory.multi_line_string(obj.map { |g| cast(g, nfactory, opts) }) elsif type == MultiPolygon nfactory.multi_polygon(obj.map { |g| cast(g, nfactory, opts) }) elsif type == GeometryCollection nfactory.collection(obj.map { |g| cast(g, nfactory, opts) }) end # Types are different elsif ntype == Point && [MultiPoint, GeometryCollection].include?(type) || [Line, LineString, LinearRing].include?(ntype) && [MultiLineString, GeometryCollection].include?(type) || ntype == Polygon && [MultiPolygon, GeometryCollection].include?(type) cast(obj.geometry_n(0), nfactory, ntype, opts) if obj.num_geometries == 1 elsif ntype == Point raise(Error::InvalidGeometry, "Cannot cast to Point") elsif ntype == Line if type == LineString && obj.num_points == 2 nfactory.line(cast(obj.point_n(0), nfactory, opts), cast(obj.point_n(1), nfactory, opts)) end elsif ntype == LinearRing nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) if type == LineString elsif ntype == LineString nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) if [Line, LinearRing].include?(type) elsif ntype == MultiPoint if type == Point nfactory.multi_point([cast(obj, nfactory, opts)]) elsif type == GeometryCollection nfactory.multi_point(obj.map { |p| cast(p, nfactory, opts) }) end elsif ntype == MultiLineString if [Line, LinearRing, LineString].include?(type) nfactory.multi_line_string([cast(obj, nfactory, opts)]) elsif type == GeometryCollection nfactory.multi_line_string(obj.map { |p| cast(p, nfactory, opts) }) end elsif ntype == MultiPolygon if type == Polygon nfactory.multi_polygon([cast(obj, nfactory, opts)]) elsif type == GeometryCollection nfactory.multi_polygon(obj.map { |p| cast(p, nfactory, opts) }) end elsif ntype == GeometryCollection if [MultiPoint, MultiLineString, MultiPolygon].include?(type) nfactory.collection(obj.map { |p| cast(p, nfactory, opts) }) else nfactory.collection([cast(obj, nfactory, opts)]) end else raise(RGeo::Error::InvalidGeometry, "Undefined type cast from #{type.name} to #{ntype.name}") end end |