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:



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rgeo/geos/zm_factory.rb', line 40

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.



34
35
36
37
# File 'lib/rgeo/geos/zm_factory.rb', line 34

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

Instance Method Details

#_create_feature(klass_, zgeometry_, mgeometry_) ⇒ Object

:nodoc:



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

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:



372
373
374
375
376
377
378
# File 'lib/rgeo/geos/zm_factory.rb', line 372

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:



380
381
382
383
384
385
386
# File 'lib/rgeo/geos/zm_factory.rb', line 380

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:



388
389
390
391
392
393
394
# File 'lib/rgeo/geos/zm_factory.rb', line 388

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:



396
397
398
399
400
401
402
# File 'lib/rgeo/geos/zm_factory.rb', line 396

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



211
212
213
# File 'lib/rgeo/geos/zm_factory.rb', line 211

def buffer_resolution
  @zfactory.buffer_resolution
end

#collection(elems_) ⇒ Object

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



299
300
301
# File 'lib/rgeo/geos/zm_factory.rb', line 299

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

#coord_sysObject

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



329
330
331
# File 'lib/rgeo/geos/zm_factory.rb', line 329

def coord_sys
  @zfactory.coord_sys
end

#encode_with(coder_) ⇒ Object

Psych support



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/rgeo/geos/zm_factory.rb', line 151

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)


235
236
237
# File 'lib/rgeo/geos/zm_factory.rb', line 235

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

#hashObject

Standard hash code



242
243
244
# File 'lib/rgeo/geos/zm_factory.rb', line 242

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

#init_with(coder_) ⇒ Object

:nodoc:



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

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)


217
218
219
# File 'lib/rgeo/geos/zm_factory.rb', line 217

def lenient_multi_polygon_assertions?
  @zfactory.lenient_multi_polygon_assertions?
end

#line(start_, end_) ⇒ Object

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



281
282
283
# File 'lib/rgeo/geos/zm_factory.rb', line 281

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



275
276
277
# File 'lib/rgeo/geos/zm_factory.rb', line 275

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



287
288
289
# File 'lib/rgeo/geos/zm_factory.rb', line 287

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.



229
230
231
# File 'lib/rgeo/geos/zm_factory.rb', line 229

def m_factory
  @mfactory
end

#marshal_dumpObject

Marshal support



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rgeo/geos/zm_factory.rb', line 101

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:



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rgeo/geos/zm_factory.rb', line 120

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



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

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



305
306
307
# File 'lib/rgeo/geos/zm_factory.rb', line 305

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



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

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



335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/rgeo/geos/zm_factory.rb', line 335

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)
      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)
      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



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

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

#parse_wkt(str_) ⇒ Object

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



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

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

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

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



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

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



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

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



323
324
325
# File 'lib/rgeo/geos/zm_factory.rb', line 323

def proj4
  @zfactory.proj4
end

#property(name_) ⇒ Object

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



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

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

#sridObject

Returns the SRID of geometries created by this factory.



204
205
206
# File 'lib/rgeo/geos/zm_factory.rb', line 204

def srid
  @zfactory.srid
end

#z_factoryObject

Returns the z-only factory corresponding to this factory.



223
224
225
# File 'lib/rgeo/geos/zm_factory.rb', line 223

def z_factory
  @zfactory
end