Class: RGeo::Geos::ZMFactory

Inherits:
Object
  • Object
show all
Includes:
Feature::Factory::Instance
Defined in:
lib/rgeo/geos/zm_factory.rb

Overview

A factory for Geos that handles both Z and M.

Constant Summary collapse

TYPE_KLASSES =

:stopdoc:

{
  Feature::Point => ZMPointImpl,
  Feature::LineString => ZMLineStringImpl,
  Feature::Line => ZMLineImpl,
  Feature::LinearRing => ZMLinearRingImpl,
  Feature::Polygon => ZMPolygonImpl,
  Feature::GeometryCollection => ZMGeometryCollectionImpl,
  Feature::MultiPoint => ZMMultiPointImpl,
  Feature::MultiLineString => ZMMultiLineStringImpl,
  Feature::MultiPolygon => ZMMultiPolygonImpl,
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts_ = {}) ⇒ ZMFactory

:nodoc:


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/rgeo/geos/zm_factory.rb', line 81

def initialize(opts_={})  # :nodoc:
  proj4_ = opts_[:proj4]
  coord_sys_ = opts_[:coord_sys]
  srid_ = opts_[:srid]
  if (!proj4_ || !coord_sys_) && srid_ && (db_ = opts_[:srs_database])
    entry_ = db_.get(srid_.to_i)
    if entry_
      proj4_ ||= entry_.proj4
      coord_sys_ ||= entry_.coord_sys
    end
  end
  srid_ ||= coord_sys_.authority_code if coord_sys_
  config_ = {
    :uses_lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions] ||
      opts_[:uses_lenient_multi_polygon_assertions],
    :buffer_resolution => opts_[:buffer_resolution], :auto_prepare => opts_[:auto_prepare],
    :wkt_generator => opts_[:wkt_generator], :wkt_parser => opts_[:wkt_parser],
    :wkb_generator => opts_[:wkb_generator], :wkb_parser => opts_[:wkb_parser],
    :srid => srid_.to_i, :proj4 => proj4_, :coord_sys => coord_sys_,
  }
  native_interface_ = opts_[:native_interface] || Geos.preferred_native_interface
  if native_interface_ == :ffi
    @zfactory = FFIFactory.new(config_.merge(:has_z_coordinate => true))
    @mfactory = FFIFactory.new(config_.merge(:has_m_coordinate => true))
  else
    @zfactory = CAPIFactory.create(config_.merge(:has_z_coordinate => true))
    @mfactory = CAPIFactory.create(config_.merge(:has_m_coordinate => true))
  end

  wkt_generator_ = opts_[:wkt_generator]
  case wkt_generator_
  when ::Hash
    @wkt_generator = WKRep::WKTGenerator.new(wkt_generator_)
  else
    @wkt_generator = WKRep::WKTGenerator.new(:convert_case => :upper)
  end
  wkb_generator_ = opts_[:wkb_generator]
  case wkb_generator_
  when ::Hash
    @wkb_generator = WKRep::WKBGenerator.new(wkb_generator_)
  else
    @wkb_generator = WKRep::WKBGenerator.new
  end
  wkt_parser_ = opts_[:wkt_parser]
  case wkt_parser_
  when ::Hash
    @wkt_parser = WKRep::WKTParser.new(self, wkt_parser_)
  else
    @wkt_parser = WKRep::WKTParser.new(self)
  end
  wkb_parser_ = opts_[:wkb_parser]
  case wkb_parser_
  when ::Hash
    @wkb_parser = WKRep::WKBParser.new(self, wkb_parser_)
  else
    @wkb_parser = WKRep::WKBParser.new(self)
  end
end

Class Method Details

.create(opts_ = {}) ⇒ Object

Create a new factory. Returns nil if the GEOS implementation is not supported.


72
73
74
75
# File 'lib/rgeo/geos/zm_factory.rb', line 72

def create(opts_={})
  return nil unless Geos.supported?
  new(opts_)
end

Instance Method Details

#_create_feature(klass_, zgeometry_, mgeometry_) ⇒ Object

:nodoc:


437
438
439
440
# File 'lib/rgeo/geos/zm_factory.rb', line 437

def _create_feature(klass_, zgeometry_, mgeometry_)  # :nodoc:
  klass_ ||= TYPE_KLASSES[zgeometry_.geometry_type] || ZMGeometryImpl
  zgeometry_ && mgeometry_ ? klass_.new(self, zgeometry_, mgeometry_) : nil
end

#_marshal_wkb_generatorObject

:nodoc:


443
444
445
446
447
448
449
# File 'lib/rgeo/geos/zm_factory.rb', line 443

def _marshal_wkb_generator  # :nodoc:
  unless defined?(@marshal_wkb_generator)
    @marshal_wkb_generator = ::RGeo::WKRep::WKBGenerator.new(
      :type_format => :wkb12)
  end
  @marshal_wkb_generator
end

#_marshal_wkb_parserObject

:nodoc:


452
453
454
455
456
457
458
# File 'lib/rgeo/geos/zm_factory.rb', line 452

def _marshal_wkb_parser  # :nodoc:
  unless defined?(@marshal_wkb_parser)
    @marshal_wkb_parser = ::RGeo::WKRep::WKBParser.new(self,
      :support_wkb12 => true)
  end
  @marshal_wkb_parser
end

#_psych_wkt_generatorObject

:nodoc:


461
462
463
464
465
466
467
# File 'lib/rgeo/geos/zm_factory.rb', line 461

def _psych_wkt_generator  # :nodoc:
  unless defined?(@psych_wkt_generator)
    @psych_wkt_generator = ::RGeo::WKRep::WKTGenerator.new(
      :tag_format => :wkt12)
  end
  @psych_wkt_generator
end

#_psych_wkt_parserObject

:nodoc:


470
471
472
473
474
475
476
# File 'lib/rgeo/geos/zm_factory.rb', line 470

def _psych_wkt_parser  # :nodoc:
  unless defined?(@psych_wkt_parser)
    @psych_wkt_parser = ::RGeo::WKRep::WKTParser.new(self,
      :support_wkt12 => true, :support_ewkt => true)
  end
  @psych_wkt_parser
end

#buffer_resolutionObject

Returns the resolution used by buffer calculations on geometries created by this factory


256
257
258
# File 'lib/rgeo/geos/zm_factory.rb', line 256

def buffer_resolution
  @zfactory.buffer_resolution
end

#collection(elems_) ⇒ Object

See ::RGeo::Feature::Factory#collection


360
361
362
# File 'lib/rgeo/geos/zm_factory.rb', line 360

def collection(elems_)
  _create_feature(ZMGeometryCollectionImpl, @zfactory.collection(elems_), @mfactory.collection(elems_))
end

#coord_sysObject

See ::RGeo::Feature::Factory#coord_sys


395
396
397
# File 'lib/rgeo/geos/zm_factory.rb', line 395

def coord_sys
  @zfactory.coord_sys
end

#encode_with(coder_) ⇒ Object

Psych support


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/rgeo/geos/zm_factory.rb', line 194

def encode_with(coder_)  # :nodoc:
  coder_['srid'] = @zfactory.srid
  coder_['buffer_resolution'] = @zfactory.buffer_resolution
  coder_['lenient_multi_polygon_assertions'] = @zfactory.lenient_multi_polygon_assertions?
  coder_['wkt_generator'] = @wkt_generator._properties
  coder_['wkb_generator'] = @wkb_generator._properties
  coder_['wkt_parser'] = @wkt_parser._properties
  coder_['wkb_parser'] = @wkb_parser._properties
  coder_['auto_prepare'] = @zfactory.property(:auto_prepare).to_s
  coder_['native_interface'] = @zfactory.is_a?(FFIFactory) ? 'ffi' : 'capi'
  if (proj4_ = @zfactory.proj4)
    str_ = proj4_.original_str || proj4_.canonical_str
    coder_['proj4'] = proj4_.radians? ? {'proj4' => str_, 'radians' => true} : str_
  end
  if (coord_sys_ = @zfactory.coord_sys)
    coder_['coord_sys'] = coord_sys_.to_wkt
  end
end

#eql?(rhs_) ⇒ Boolean Also known as: ==

Factory equivalence test.

Returns:

  • (Boolean)

284
285
286
# File 'lib/rgeo/geos/zm_factory.rb', line 284

def eql?(rhs_)
  rhs_.is_a?(ZMFactory) && rhs_.z_factory == @zfactory
end

#hashObject

Standard hash code


292
293
294
# File 'lib/rgeo/geos/zm_factory.rb', line 292

def hash
  @hash ||= [@zfactory, @mfactory].hash
end

#init_with(coder_) ⇒ Object

:nodoc:


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
# File 'lib/rgeo/geos/zm_factory.rb', line 213

def init_with(coder_)  # :nodoc:
  if (proj4_data_ = coder_['proj4'])
    if proj4_data_.is_a?(::Hash)
      proj4_ = CoordSys::Proj4.create(proj4_data_['proj4'], :radians => proj4_data_['radians'])
    else
      proj4_ = CoordSys::Proj4.create(proj4_data_.to_s)
    end
  else
    proj4_ = nil
  end
  if (coord_sys_data_ = coder_['cs'])
    coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_data_.to_s)
  else
    coord_sys_ = nil
  end
  initialize(
    :native_interface => coder_['native_interface'] == 'ffi' ? :ffi : :capi,
    :has_z_coordinate => coder_['has_z_coordinate'],
    :has_m_coordinate => coder_['has_m_coordinate'],
    :srid => coder_['srid'],
    :buffer_resolution => coder_['buffer_resolution'],
    :wkt_generator => ImplHelper::Utils.symbolize_hash(coder_['wkt_generator']),
    :wkb_generator => ImplHelper::Utils.symbolize_hash(coder_['wkb_generator']),
    :wkt_parser => ImplHelper::Utils.symbolize_hash(coder_['wkt_parser']),
    :wkb_parser => ImplHelper::Utils.symbolize_hash(coder_['wkb_parser']),
    :auto_prepare => coder_['auto_prepare'] == 'disabled' ? :disabled : :simple,
    :uses_lenient_multi_polygon_assertions => coder_['lenient_multi_polygon_assertions'],
    :proj4 => proj4_,
    :coord_sys => coord_sys_
  )
end

#lenient_multi_polygon_assertions?Boolean

Returns true if this factory is lenient with MultiPolygon assertions

Returns:

  • (Boolean)

263
264
265
# File 'lib/rgeo/geos/zm_factory.rb', line 263

def lenient_multi_polygon_assertions?
  @zfactory.lenient_multi_polygon_assertions?
end

#line(start_, end_) ⇒ Object

See ::RGeo::Feature::Factory#line


339
340
341
# File 'lib/rgeo/geos/zm_factory.rb', line 339

def line(start_, end_)
  _create_feature(ZMLineImpl, @zfactory.line(start_, end_), @mfactory.line(start_, end_))
end

#line_string(points_) ⇒ Object

See ::RGeo::Feature::Factory#line_string


332
333
334
# File 'lib/rgeo/geos/zm_factory.rb', line 332

def line_string(points_)
  _create_feature(ZMLineStringImpl, @zfactory.line_string(points_), @mfactory.line_string(points_))
end

#linear_ring(points_) ⇒ Object

See ::RGeo::Feature::Factory#linear_ring


346
347
348
# File 'lib/rgeo/geos/zm_factory.rb', line 346

def linear_ring(points_)
  _create_feature(ZMLinearRingImpl, @zfactory.linear_ring(points_), @mfactory.linear_ring(points_))
end

#m_factoryObject

Returns the m-only factory corresponding to this factory.


277
278
279
# File 'lib/rgeo/geos/zm_factory.rb', line 277

def m_factory
  @mfactory
end

#marshal_dumpObject

Marshal support


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/rgeo/geos/zm_factory.rb', line 143

def marshal_dump  # :nodoc:
  hash_ = {
    'srid' => @zfactory.srid,
    'bufr' => @zfactory.buffer_resolution,
    'wktg' => @wkt_generator._properties,
    'wkbg' => @wkb_generator._properties,
    'wktp' => @wkt_parser._properties,
    'wkbp' => @wkb_parser._properties,
    'lmpa' => @zfactory.lenient_multi_polygon_assertions?,
    'apre' => @zfactory.property(:auto_prepare) == :simple,
    'nffi' => @zfactory.is_a?(FFIFactory),
  }
  proj4_ = @zfactory.proj4
  coord_sys_ = @zfactory.coord_sys
  hash_['proj4'] = proj4_.marshal_dump if proj4_
  hash_['cs'] = coord_sys_.to_wkt if coord_sys_
  hash_
end

#marshal_load(data_) ⇒ Object

:nodoc:


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
# File 'lib/rgeo/geos/zm_factory.rb', line 162

def marshal_load(data_)  # :nodoc:
  if CoordSys::Proj4.supported? && (proj4_data_ = data_['proj4'])
    proj4_ = CoordSys::Proj4.allocate
    proj4_.marshal_load(proj4_data_)
  else
    proj4_ = nil
  end
  if (coord_sys_data_ = data_['cs'])
    coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_data_)
  else
    coord_sys_ = nil
  end
  initialize(
    :native_interface => (data_['nffi'] ? :ffi : :capi),
    :has_z_coordinate => data_['hasz'],
    :has_m_coordinate => data_['hasm'],
    :srid => data_['srid'],
    :buffer_resolution => data_['bufr'],
    :wkt_generator => ImplHelper::Utils.symbolize_hash(data_['wktg']),
    :wkb_generator => ImplHelper::Utils.symbolize_hash(data_['wkbg']),
    :wkt_parser => ImplHelper::Utils.symbolize_hash(data_['wktp']),
    :wkb_parser => ImplHelper::Utils.symbolize_hash(data_['wkbp']),
    :uses_lenient_multi_polygon_assertions => data_['lmpa'],
    :auto_prepare => (data_['apre'] ? :simple : :disabled),
    :proj4 => proj4_,
    :coord_sys => coord_sys_
  )
end

#multi_line_string(elems_) ⇒ Object

See ::RGeo::Feature::Factory#multi_line_string


374
375
376
# File 'lib/rgeo/geos/zm_factory.rb', line 374

def multi_line_string(elems_)
  _create_feature(ZMMultiLineStringImpl, @zfactory.multi_line_string(elems_), @mfactory.multi_line_string(elems_))
end

#multi_point(elems_) ⇒ Object

See ::RGeo::Feature::Factory#multi_point


367
368
369
# File 'lib/rgeo/geos/zm_factory.rb', line 367

def multi_point(elems_)
  _create_feature(ZMMultiPointImpl, @zfactory.multi_point(elems_), @mfactory.multi_point(elems_))
end

#multi_polygon(elems_) ⇒ Object

See ::RGeo::Feature::Factory#multi_polygon


381
382
383
# File 'lib/rgeo/geos/zm_factory.rb', line 381

def multi_polygon(elems_)
  _create_feature(ZMMultiPolygonImpl, @zfactory.multi_polygon(elems_), @mfactory.multi_polygon(elems_))
end

#override_cast(original_, ntype_, flags_) ⇒ Object

See ::RGeo::Feature::Factory#override_cast


402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/rgeo/geos/zm_factory.rb', line 402

def override_cast(original_, ntype_, flags_)
  return nil unless Geos.supported?
  keep_subtype_ = flags_[:keep_subtype]  #force_new_ = flags_[:force_new]

  project_ = flags_[:project]
  type_ = original_.geometry_type
  ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
  case original_
  when ZMGeometryMethods    # Optimization if we're just changing factories, but to
    # another ZM factory.

    if original_.factory != self && ntype_ == type_ &&
        (!project_ || original_.factory.proj4 == @proj4)
    then
      zresult_ = original_.z_geometry.dup
      zresult_._set_factory(@zfactory)
      mresult_ = original_.m_geometry.dup
      mresult_._set_factory(@mfactory)
      return original_.class.create(self, zresult_, mresult_)
    end    # LineString conversion optimization.

    if (original_.factory != self || ntype_ != type_) &&
        (!project_ || original_.factory.proj4 == @proj4) &&
        type_.subtype_of?(Feature::LineString) && ntype_.subtype_of?(Feature::LineString)
    then
      klass_ = Factory::IMPL_CLASSES[ntype_]
      zresult_ = klass_._copy_from(@zfactory, original_.z_geometry)
      mresult_ = klass_._copy_from(@mfactory, original_.m_geometry)
      return ZMLineStringImpl.create(self, zresult_, mresult_)
    end
  end
  false
end

#parse_wkb(str_) ⇒ Object

See ::RGeo::Feature::Factory#parse_wkb


318
319
320
# File 'lib/rgeo/geos/zm_factory.rb', line 318

def parse_wkb(str_)
  @wkb_parser.parse(str_)
end

#parse_wkt(str_) ⇒ Object

See ::RGeo::Feature::Factory#parse_wkt


311
312
313
# File 'lib/rgeo/geos/zm_factory.rb', line 311

def parse_wkt(str_)
  @wkt_parser.parse(str_)
end

#point(x_, y_, z_ = 0, m_ = 0) ⇒ Object

See ::RGeo::Feature::Factory#point


325
326
327
# File 'lib/rgeo/geos/zm_factory.rb', line 325

def point(x_, y_, z_=0, m_=0)
  _create_feature(ZMPointImpl, @zfactory.point(x_, y_, z_), @mfactory.point(x_, y_, m_))
end

#polygon(outer_ring_, inner_rings_ = nil) ⇒ Object

See ::RGeo::Feature::Factory#polygon


353
354
355
# File 'lib/rgeo/geos/zm_factory.rb', line 353

def polygon(outer_ring_, inner_rings_=nil)
  _create_feature(ZMPolygonImpl, @zfactory.polygon(outer_ring_, inner_rings_), @mfactory.polygon(outer_ring_, inner_rings_))
end

#proj4Object

See ::RGeo::Feature::Factory#proj4


388
389
390
# File 'lib/rgeo/geos/zm_factory.rb', line 388

def proj4
  @zfactory.proj4
end

#property(name_) ⇒ Object

See ::RGeo::Feature::Factory#property


299
300
301
302
303
304
305
306
# File 'lib/rgeo/geos/zm_factory.rb', line 299

def property(name_)
  case name_
  when :has_z_coordinate, :has_m_coordinate, :is_cartesian
    true
  else
    nil
  end
end

#sridObject

Returns the SRID of geometries created by this factory.


248
249
250
# File 'lib/rgeo/geos/zm_factory.rb', line 248

def srid
  @zfactory.srid
end

#z_factoryObject

Returns the z-only factory corresponding to this factory.


270
271
272
# File 'lib/rgeo/geos/zm_factory.rb', line 270

def z_factory
  @zfactory
end