Class: RGeo::Geos::ZMFactory

Inherits:
Object
  • Object
show all
Includes:
Feature::Factory::Instance, ImplHelper::Utils
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

Methods included from ImplHelper::Utils

setup_coord_sys

Constructor Details

#initialize(opts = {}) ⇒ ZMFactory

:nodoc:



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

def initialize(opts = {}) # :nodoc:
  coord_sys = opts[:coord_sys]
  srid = opts[:srid]
  srid ||= coord_sys.authority_code if coord_sys
  config = {
    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, 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]
  @wkt_generator =
    case wkt_generator
    when Hash
      WKRep::WKTGenerator.new(wkt_generator)
    else
      WKRep::WKTGenerator.new(convert_case: :upper)
    end
  wkb_generator = opts[:wkb_generator]
  @wkb_generator =
    case wkb_generator
    when Hash
      WKRep::WKBGenerator.new(wkb_generator)
    else
      WKRep::WKBGenerator.new
    end
  wkt_parser = opts[:wkt_parser]
  @wkt_parser =
    case wkt_parser
    when Hash
      WKRep::WKTParser.new(self, wkt_parser)
    else
      WKRep::WKTParser.new(self)
    end
  wkb_parser = opts[:wkb_parser]
  @wkb_parser =
    case wkb_parser
    when Hash
      WKRep::WKBParser.new(self, wkb_parser)
    else
      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.



36
37
38
39
# File 'lib/rgeo/geos/zm_factory.rb', line 36

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

Instance Method Details

#buffer_resolutionObject

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



177
178
179
# File 'lib/rgeo/geos/zm_factory.rb', line 177

def buffer_resolution
  @zfactory.buffer_resolution
end

#collection(elems) ⇒ Object

See RGeo::Feature::Factory#collection



267
268
269
# File 'lib/rgeo/geos/zm_factory.rb', line 267

def collection(elems)
  create_feature(ZMGeometryCollectionImpl, @zfactory.collection(elems), @mfactory.collection(elems))
end

#coord_sysObject

See RGeo::Feature::Factory#coord_sys



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

def coord_sys
  @zfactory.coord_sys
end

#create_feature(klass, zgeometry, mgeometry) ⇒ Object

:nodoc:



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

def create_feature(klass, zgeometry, mgeometry) # :nodoc:
  klass ||= TYPE_KLASSES[zgeometry.geometry_type] || ZMGeometryImpl
  zgeometry && mgeometry ? klass.new(self, zgeometry, mgeometry) : nil
end

#encode_with(coder) ⇒ Object

Psych support



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rgeo/geos/zm_factory.rb', line 134

def encode_with(coder) # :nodoc:
  coder["srid"] = @zfactory.srid
  coder["buffer_resolution"] = @zfactory.buffer_resolution
  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"

  return unless (coord_sys = @zfactory.coord_sys)

  coder["coord_sys"] = coord_sys.to_wkt
end

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

Factory equivalence test.

Returns:

  • (Boolean)


195
196
197
# File 'lib/rgeo/geos/zm_factory.rb', line 195

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

#hashObject

Standard hash code



202
203
204
# File 'lib/rgeo/geos/zm_factory.rb', line 202

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

#init_with(coder) ⇒ Object

:nodoc:



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

def init_with(coder) # :nodoc:
  cs_class = CoordSys::CONFIG.default_coord_sys_class
  coord_sys = coder["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }

  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: symbolize_hash(coder["wkt_generator"]),
    wkb_generator: symbolize_hash(coder["wkb_generator"]),
    wkt_parser: symbolize_hash(coder["wkt_parser"]),
    wkb_parser: symbolize_hash(coder["wkb_parser"]),
    auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
    coord_sys: coord_sys
  )
end

#line(start, stop) ⇒ Object

See RGeo::Feature::Factory#line



245
246
247
# File 'lib/rgeo/geos/zm_factory.rb', line 245

def line(start, stop)
  create_feature(ZMLineImpl, @zfactory.line(start, stop), @mfactory.line(start, stop))
end

#line_string(points) ⇒ Object

See RGeo::Feature::Factory#line_string



239
240
241
# File 'lib/rgeo/geos/zm_factory.rb', line 239

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



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

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.



189
190
191
# File 'lib/rgeo/geos/zm_factory.rb', line 189

def m_factory
  @mfactory
end

#marshal_dumpObject

Marshal support



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/rgeo/geos/zm_factory.rb', line 97

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,
    "apre" => @zfactory.property(:auto_prepare) == :simple,
    "nffi" => @zfactory.is_a?(FFIFactory)
  }
  coord_sys = @zfactory.coord_sys
  hash["cs"] = coord_sys.to_wkt if coord_sys
  hash
end

#marshal_load(data) ⇒ Object

:nodoc:



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/rgeo/geos/zm_factory.rb', line 113

def marshal_load(data) # :nodoc:
  cs_class = CoordSys::CONFIG.default_coord_sys_class
  coord_sys = data["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }

  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: symbolize_hash(data["wktg"]),
    wkb_generator: symbolize_hash(data["wkbg"]),
    wkt_parser: symbolize_hash(data["wktp"]),
    wkb_parser: symbolize_hash(data["wkbp"]),
    auto_prepare: (data["apre"] ? :simple : :disabled),
    coord_sys: coord_sys
  )
end

#marshal_wkb_generatorObject



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

def marshal_wkb_generator
  @marshal_wkb_generator ||= RGeo::WKRep::WKBGenerator.new(typeformat: :wkb12)
end

#marshal_wkb_parserObject



337
338
339
# File 'lib/rgeo/geos/zm_factory.rb', line 337

def marshal_wkb_parser
  @marshal_wkb_parser ||= RGeo::WKRep::WKBParser.new(self, support_wkb12: true)
end

#multi_line_string(elems) ⇒ Object

See RGeo::Feature::Factory#multi_line_string



279
280
281
# File 'lib/rgeo/geos/zm_factory.rb', line 279

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



273
274
275
# File 'lib/rgeo/geos/zm_factory.rb', line 273

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



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

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



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/rgeo/geos/zm_factory.rb', line 297

def override_cast(original, ntype, flags)
  return unless Geos.supported?
  keep_subtype = flags[:keep_subtype]
  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.coord_sys == @coord_sys)
      zresult = original.z_geometry.dup
      zresult.factory = @zfactory
      mresult = original.m_geometry.dup
      mresult.factory = @mfactory
      return original.class.create(self, zresult, mresult)
    end
    # LineString conversion optimization.
    if (original.factory != self || ntype != type) &&
        (!project || original.factory.coord_sys == @coord_sys) &&
        type.subtypeof?(Feature::LineString) && ntype.subtypeof?(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



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

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

#parse_wkt(str) ⇒ Object

See RGeo::Feature::Factory#parse_wkt



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

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

#point(x, y, z = 0, m = 0) ⇒ Object

See RGeo::Feature::Factory#point



229
230
231
232
233
234
235
# File 'lib/rgeo/geos/zm_factory.rb', line 229

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



257
258
259
260
261
262
263
# File 'lib/rgeo/geos/zm_factory.rb', line 257

def polygon(outer_ring, inner_rings = nil)
  create_feature(
    ZMPolygonImpl,
    @zfactory.polygon(outer_ring, inner_rings),
    @mfactory.polygon(outer_ring, inner_rings)
  )
end

#property(name) ⇒ Object

See RGeo::Feature::Factory#property



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

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

#psych_wkt_generatorObject



341
342
343
# File 'lib/rgeo/geos/zm_factory.rb', line 341

def psych_wkt_generator
  @psych_wkt_generator ||= RGeo::WKRep::WKTGenerator.new(tag_format: :wkt12)
end

#psych_wkt_parserObject



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

def psych_wkt_parser
  @psych_wkt_parser ||= RGeo::WKRep::WKTParser.new(self, support_wkt12: true, support_ewkt: true)
end

#sridObject

Returns the SRID of geometries created by this factory.



170
171
172
# File 'lib/rgeo/geos/zm_factory.rb', line 170

def srid
  @zfactory.srid
end

#z_factoryObject

Returns the z-only factory corresponding to this factory.



183
184
185
# File 'lib/rgeo/geos/zm_factory.rb', line 183

def z_factory
  @zfactory
end